[Clang][Sema] Prevent implicit casting Complex type to Vector (#187954)

Emitting an error message in case of implicit casting of a complex type
to a built-in vector type in C

Fixes: #186805
This commit is contained in:
Amr Hesham 2026-04-03 21:10:58 +02:00 committed by GitHub
parent 8d34545792
commit a4632f6294
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 16 deletions

View File

@ -358,6 +358,8 @@ Improvements to Clang's diagnostics
- Improved ``-Wgnu-zero-variadic-macro-arguments`` to suggest using
``__VA_OPT__`` if the current language version supports it(#GH188624)
- Clang now emits an error when implicitly casting a complex type to a built-in vector type. (#GH186805)
Improvements to Clang's time-trace
----------------------------------

View File

@ -4501,6 +4501,8 @@ def warn_impcast_float_result_precision : Warning<
def warn_impcast_double_promotion : Warning<
"implicit conversion increases floating-point precision: %0 to %1">,
InGroup<DoublePromotion>, DefaultIgnore;
def err_impcast_incompatible_type : Error<
"implicit conversion from %0 to incompatible type %1">;
def warn_impcast_integer_sign : Warning<
"implicit conversion changes signedness: %0 to %1">,
InGroup<SignConversion>, DefaultIgnore;

View File

@ -13003,6 +13003,27 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC,
else if (auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
ObjC().checkDictionaryLiteral(QualType(Target, 0), DictionaryLiteral);
// Strip complex types.
if (isa<ComplexType>(Source)) {
if (!isa<ComplexType>(Target)) {
if (SourceMgr.isInSystemMacro(CC) || Target->isBooleanType())
return;
if (!getLangOpts().CPlusPlus && Target->isVectorType()) {
return DiagnoseImpCast(*this, E, T, CC,
diag::err_impcast_incompatible_type);
}
return DiagnoseImpCast(*this, E, T, CC,
getLangOpts().CPlusPlus
? diag::err_impcast_complex_scalar
: diag::warn_impcast_complex_scalar);
}
Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
Target = cast<ComplexType>(Target)->getElementType().getTypePtr();
}
// Strip vector types.
if (isa<VectorType>(Source)) {
if (Target->isSveVLSBuiltinType() &&
@ -13065,22 +13086,6 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC,
if (const auto *MatTy = dyn_cast<ConstantMatrixType>(Target))
Target = MatTy->getElementType().getTypePtr();
// Strip complex types.
if (isa<ComplexType>(Source)) {
if (!isa<ComplexType>(Target)) {
if (SourceMgr.isInSystemMacro(CC) || Target->isBooleanType())
return;
return DiagnoseImpCast(*this, E, T, CC,
getLangOpts().CPlusPlus
? diag::err_impcast_complex_scalar
: diag::warn_impcast_complex_scalar);
}
Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
Target = cast<ComplexType>(Target)->getElementType().getTypePtr();
}
const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
const BuiltinType *TargetBT = dyn_cast<BuiltinType>(Target);

View File

@ -0,0 +1,13 @@
// RUN: %clang_cc1 -fsyntax-only -verify=c %s
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=cxx %s
typedef char __attribute__((__vector_size__(64))) V;
void implicit_cast_complex_to_vector() {
_Complex double x;
V y;
// c-error@+2 {{implicit conversion from '_Complex double' to incompatible type 'V' (vector of 64 'char' values)}}
// cxx-error@+1 {{implicit conversion from '_Complex double' to 'V' (vector of 64 'char' values) is not permitted in C++}}
V z = x + y;
}