-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[Clang][Sema] Fix missing warning when comparing mismatched enums in … #81389
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…C mode Factored logic from `CheckImplicitConversion` into new methods `Expr::getEnumConstantDecl` and `Expr::getEnumCoercedType` for use in `checkEnumArithmeticConversions`. Fix llvm#29217
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write If you have received no comments on your PR for a week, you can request a review If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-clang Author: None (44-2-Kupa-Martin) Changes…C mode Factored logic from Fix #29217 Patch is 650.51 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/81389.diff 9 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ece6013f672621..00ddf0b9656a31 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -161,6 +161,9 @@ Improvements to Clang's time-trace
Bug Fixes in This Version
-------------------------
+- Fixed missing warnings when comparing mismatched enumeration constants
+ in C (`#29217 <https://github.com/llvm/llvm-project/issues/29217>`).
+
- Clang now accepts elaborated-type-specifiers that explicitly specialize
a member class template for an implicit instantiation of a class template.
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 3fc481a62a78a9..4f11f3eb610564 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -40,26 +40,26 @@
#include <optional>
namespace clang {
- class APValue;
- class ASTContext;
- class BlockDecl;
- class CXXBaseSpecifier;
- class CXXMemberCallExpr;
- class CXXOperatorCallExpr;
- class CastExpr;
- class Decl;
- class IdentifierInfo;
- class MaterializeTemporaryExpr;
- class NamedDecl;
- class ObjCPropertyRefExpr;
- class OpaqueValueExpr;
- class ParmVarDecl;
- class StringLiteral;
- class TargetInfo;
- class ValueDecl;
+class APValue;
+class ASTContext;
+class BlockDecl;
+class CXXBaseSpecifier;
+class CXXMemberCallExpr;
+class CXXOperatorCallExpr;
+class CastExpr;
+class Decl;
+class IdentifierInfo;
+class MaterializeTemporaryExpr;
+class NamedDecl;
+class ObjCPropertyRefExpr;
+class OpaqueValueExpr;
+class ParmVarDecl;
+class StringLiteral;
+class TargetInfo;
+class ValueDecl;
/// A simple array of base specifiers.
-typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
+typedef SmallVector<CXXBaseSpecifier *, 4> CXXCastPath;
/// An adjustment to be made to the temporary created when emitting a
/// reference binding, which accesses a particular subobject of that temporary.
@@ -88,7 +88,7 @@ struct SubobjectAdjustment {
SubobjectAdjustment(const CastExpr *BasePath,
const CXXRecordDecl *DerivedClass)
- : Kind(DerivedToBaseAdjustment) {
+ : Kind(DerivedToBaseAdjustment) {
DerivedToBase.BasePath = BasePath;
DerivedToBase.DerivedClass = DerivedClass;
}
@@ -98,7 +98,7 @@ struct SubobjectAdjustment {
}
SubobjectAdjustment(const MemberPointerType *MPT, Expr *RHS)
- : Kind(MemberPointerAdjustment) {
+ : Kind(MemberPointerAdjustment) {
this->Ptr.MPT = MPT;
this->Ptr.RHS = RHS;
}
@@ -112,10 +112,10 @@ class Expr : public ValueStmt {
public:
Expr() = delete;
- Expr(const Expr&) = delete;
+ Expr(const Expr &) = delete;
Expr(Expr &&) = delete;
- Expr &operator=(const Expr&) = delete;
- Expr &operator=(Expr&&) = delete;
+ Expr &operator=(const Expr &) = delete;
+ Expr &operator=(Expr &&) = delete;
protected:
Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK)
@@ -128,7 +128,7 @@ class Expr : public ValueStmt {
}
/// Construct an empty expression.
- explicit Expr(StmtClass SC, EmptyShell) : ValueStmt(SC) { }
+ explicit Expr(StmtClass SC, EmptyShell) : ValueStmt(SC) {}
/// Each concrete expr subclass is expected to compute its dependence and call
/// this in the constructor.
@@ -153,6 +153,12 @@ class Expr : public ValueStmt {
TR = t;
}
+ /// If this expression is an enumeration constant, return the
+ /// enumeration type under which said constant was declared.
+ /// Otherwise return the expression's type.
+ /// Note this effectively circumvents the weak typing of C's enum constants
+ QualType getEnumCoercedType(const ASTContext &Ctx) const;
+
ExprDependence getDependence() const {
return static_cast<ExprDependence>(ExprBits.Dependent);
}
@@ -294,7 +300,7 @@ class Expr : public ValueStmt {
MLV_IncompleteVoidType,
MLV_DuplicateVectorComponents,
MLV_InvalidExpression,
- MLV_LValueCast, // Specialized form of MLV_InvalidExpression.
+ MLV_LValueCast, // Specialized form of MLV_InvalidExpression.
MLV_IncompleteType,
MLV_ConstQualified,
MLV_ConstQualifiedField,
@@ -327,25 +333,26 @@ class Expr : public ValueStmt {
enum Kinds {
CL_LValue,
CL_XValue,
- CL_Function, // Functions cannot be lvalues in C.
- CL_Void, // Void cannot be an lvalue in C.
+ CL_Function, // Functions cannot be lvalues in C.
+ CL_Void, // Void cannot be an lvalue in C.
CL_AddressableVoid, // Void expression whose address can be taken in C.
CL_DuplicateVectorComponents, // A vector shuffle with dupes.
CL_MemberFunction, // An expression referring to a member function
CL_SubObjCPropertySetting,
- CL_ClassTemporary, // A temporary of class type, or subobject thereof.
- CL_ArrayTemporary, // A temporary of array type.
+ CL_ClassTemporary, // A temporary of class type, or subobject thereof.
+ CL_ArrayTemporary, // A temporary of array type.
CL_ObjCMessageRValue, // ObjC message is an rvalue
- CL_PRValue // A prvalue for any other reason, of any other type
+ CL_PRValue // A prvalue for any other reason, of any other type
};
/// The results of modification testing.
enum ModifiableType {
CM_Untested, // testModifiable was false.
CM_Modifiable,
- CM_RValue, // Not modifiable because it's an rvalue
- CM_Function, // Not modifiable because it's a function; C++ only
+ CM_RValue, // Not modifiable because it's an rvalue
+ CM_Function, // Not modifiable because it's a function; C++ only
CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
- CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
+ CM_NoSetterProperty, // Implicit assignment to ObjC property without
+ // setter
CM_ConstQualified,
CM_ConstQualifiedField,
CM_ConstAddrSpace,
@@ -360,8 +367,7 @@ class Expr : public ValueStmt {
unsigned short Modifiable;
explicit Classification(Kinds k, ModifiableType m)
- : Kind(k), Modifiable(m)
- {}
+ : Kind(k), Modifiable(m) {}
public:
Classification() {}
@@ -382,7 +388,6 @@ class Expr : public ValueStmt {
static Classification makeSimpleLValue() {
return Classification(CL_LValue, CM_Modifiable);
}
-
};
/// Classify - Classify this expression according to the C++11
/// expression taxonomy.
@@ -408,7 +413,8 @@ class Expr : public ValueStmt {
/// expression is modifiable (C99 6.3.2.1p1).
/// \param Loc A source location that might be filled with a relevant location
/// if the expression is not modifiable.
- Classification ClassifyModifiable(ASTContext &Ctx, SourceLocation &Loc) const{
+ Classification ClassifyModifiable(ASTContext &Ctx,
+ SourceLocation &Loc) const {
return ClassifyImpl(Ctx, &Loc);
}
@@ -421,9 +427,9 @@ class Expr : public ValueStmt {
static ExprValueKind getValueKindForType(QualType T) {
if (const ReferenceType *RT = T->getAs<ReferenceType>())
return (isa<LValueReferenceType>(RT)
- ? VK_LValue
- : (RT->getPointeeType()->isFunctionType()
- ? VK_LValue : VK_XValue));
+ ? VK_LValue
+ : (RT->getPointeeType()->isFunctionType() ? VK_LValue
+ : VK_XValue));
return VK_PRValue;
}
@@ -454,7 +460,6 @@ class Expr : public ValueStmt {
Classification ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const;
public:
-
/// Returns true if this expression is a gl-value that
/// potentially refers to a bit-field.
///
@@ -472,12 +477,19 @@ class Expr : public ValueStmt {
FieldDecl *getSourceBitField();
const FieldDecl *getSourceBitField() const {
- return const_cast<Expr*>(this)->getSourceBitField();
+ return const_cast<Expr *>(this)->getSourceBitField();
+ }
+
+ /// If this expression refers to an enum constant, retrieve its declaration
+ EnumConstantDecl *getEnumConstantDecl();
+
+ const EnumConstantDecl *getEnumConstantDecl() const {
+ return const_cast<Expr *>(this)->getEnumConstantDecl();
}
Decl *getReferencedDeclOfCallee();
const Decl *getReferencedDeclOfCallee() const {
- return const_cast<Expr*>(this)->getReferencedDeclOfCallee();
+ return const_cast<Expr *>(this)->getReferencedDeclOfCallee();
}
/// If this expression is an l-value for an Objective C
@@ -500,9 +512,7 @@ class Expr : public ValueStmt {
bool refersToGlobalRegisterVar() const;
/// Returns whether this expression has a placeholder type.
- bool hasPlaceholderType() const {
- return getType()->isPlaceholderType();
- }
+ bool hasPlaceholderType() const { return getType()->isPlaceholderType(); }
/// Returns whether this expression has a specific placeholder type.
bool hasPlaceholderType(BuiltinType::Kind K) const {
@@ -562,19 +572,18 @@ class Expr : public ValueStmt {
/// might be usable in a constant expression in C++11, if it were marked
/// constexpr. Return false if the function can never produce a constant
/// expression, along with diagnostics describing why not.
- static bool isPotentialConstantExpr(const FunctionDecl *FD,
- SmallVectorImpl<
- PartialDiagnosticAt> &Diags);
+ static bool
+ isPotentialConstantExpr(const FunctionDecl *FD,
+ SmallVectorImpl<PartialDiagnosticAt> &Diags);
/// isPotentialConstantExprUnevaluated - Return true if this expression might
/// be usable in a constant expression in C++11 in an unevaluated context, if
/// it were in function FD marked constexpr. Return false if the function can
/// never produce a constant expression, along with diagnostics describing
/// why not.
- static bool isPotentialConstantExprUnevaluated(Expr *E,
- const FunctionDecl *FD,
- SmallVectorImpl<
- PartialDiagnosticAt> &Diags);
+ static bool isPotentialConstantExprUnevaluated(
+ Expr *E, const FunctionDecl *FD,
+ SmallVectorImpl<PartialDiagnosticAt> &Diags);
/// isConstantInitializer - Returns true if this expression can be emitted to
/// IR as a constant, and thus can be used as a constant initializer in C.
@@ -620,9 +629,7 @@ class Expr : public ValueStmt {
// hasSideEffects - Return true if the evaluated expression has
// side effects.
- bool hasSideEffects() const {
- return HasSideEffects;
- }
+ bool hasSideEffects() const { return HasSideEffects; }
};
/// EvalResult is a struct with detailed info about an evaluated expression.
@@ -729,7 +736,7 @@ class Expr : public ValueStmt {
/// constant.
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
const FunctionDecl *Callee,
- ArrayRef<const Expr*> Args,
+ ArrayRef<const Expr *> Args,
const Expr *This = nullptr) const;
enum class ConstantExprKind {
@@ -815,9 +822,9 @@ class Expr : public ValueStmt {
/// isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to
/// a Null pointer constant. The return value can further distinguish the
/// kind of NULL pointer constant that was detected.
- NullPointerConstantKind isNullPointerConstant(
- ASTContext &Ctx,
- NullPointerConstantValueDependence NPC) const;
+ NullPointerConstantKind
+ isNullPointerConstant(ASTContext &Ctx,
+ NullPointerConstantValueDependence NPC) const;
/// isOBJCGCCandidate - Return true if this expression may be used in a read/
/// write barrier.
@@ -1003,7 +1010,7 @@ class Expr : public ValueStmt {
/// Checks that the two Expr's will refer to the same value as a comparison
/// operand. The caller must ensure that the values referenced by the Expr's
/// are not modified between E1 and E2 or the result my be invalid.
- static bool isSameComparisonOperand(const Expr* E1, const Expr* E2);
+ static bool isSameComparisonOperand(const Expr *E1, const Expr *E2);
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstExprConstant &&
@@ -1025,16 +1032,16 @@ using ConstantExprKind = Expr::ConstantExprKind;
/// FullExpr - Represents a "full-expression" node.
class FullExpr : public Expr {
protected:
- Stmt *SubExpr;
-
- FullExpr(StmtClass SC, Expr *subexpr)
- : Expr(SC, subexpr->getType(), subexpr->getValueKind(),
- subexpr->getObjectKind()),
- SubExpr(subexpr) {
- setDependence(computeDependence(this));
- }
- FullExpr(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty) {}
+ Stmt *SubExpr;
+
+ FullExpr(StmtClass SC, Expr *subexpr)
+ : Expr(SC, subexpr->getType(), subexpr->getValueKind(),
+ subexpr->getObjectKind()),
+ SubExpr(subexpr) {
+ setDependence(computeDependence(this));
+ }
+ FullExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {}
+
public:
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
@@ -1137,7 +1144,7 @@ class ConstantExpr final
APValue getAPValueResult() const;
llvm::APSInt getResultAsAPSInt() const;
// Iterators
- child_range children() { return child_range(&SubExpr, &SubExpr+1); }
+ child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
const_child_range children() const {
return const_child_range(&SubExpr, &SubExpr + 1);
}
@@ -1171,7 +1178,7 @@ class OpaqueValueExpr : public Expr {
static const OpaqueValueExpr *findInCopyConstruct(const Expr *expr);
explicit OpaqueValueExpr(EmptyShell Empty)
- : Expr(OpaqueValueExprClass, Empty) {}
+ : Expr(OpaqueValueExprClass, Empty) {}
/// Retrieve the location of this expression.
SourceLocation getLocation() const { return OpaqueValueExprBits.Loc; }
@@ -1483,7 +1490,7 @@ class IntegerLiteral : public Expr, public APIntStorage {
/// Construct an empty integer literal.
explicit IntegerLiteral(EmptyShell Empty)
- : Expr(IntegerLiteralClass, Empty) { }
+ : Expr(IntegerLiteralClass, Empty) {}
public:
// type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
@@ -1529,7 +1536,7 @@ class FixedPointLiteral : public Expr, public APIntStorage {
explicit FixedPointLiteral(EmptyShell Empty)
: Expr(FixedPointLiteralClass, Empty) {}
- public:
+public:
FixedPointLiteral(const ASTContext &C, const llvm::APInt &V, QualType type,
SourceLocation l, unsigned Scale);
@@ -1573,6 +1580,7 @@ enum class CharacterLiteralKind { Ascii, Wide, UTF8, UTF16, UTF32 };
class CharacterLiteral : public Expr {
unsigned Value;
SourceLocation Loc;
+
public:
// type should be IntTy
CharacterLiteral(unsigned value, CharacterLiteralKind kind, QualType type,
@@ -1584,7 +1592,7 @@ class CharacterLiteral : public Expr {
}
/// Construct an empty character literal.
- CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { }
+ CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) {}
SourceLocation getLocation() const { return Loc; }
CharacterLiteralKind getKind() const {
@@ -1698,6 +1706,7 @@ class FloatingLiteral : public Expr, private APFloatStorage {
///
class ImaginaryLiteral : public Expr {
Stmt *Val;
+
public:
ImaginaryLiteral(Expr *val, QualType Ty)
: Expr(ImaginaryLiteralClass, Ty, VK_PRValue, OK_Ordinary), Val(val) {
@@ -1706,7 +1715,7 @@ class ImaginaryLiteral : public Expr {
/// Build an empty imaginary literal.
explicit ImaginaryLiteral(EmptyShell Empty)
- : Expr(ImaginaryLiteralClass, Empty) { }
+ : Expr(ImaginaryLiteralClass, Empty) {}
const Expr *getSubExpr() const { return cast<Expr>(Val); }
Expr *getSubExpr() { return cast<Expr>(Val); }
@@ -1722,7 +1731,7 @@ class ImaginaryLiteral : public Expr {
}
// Iterators
- child_range children() { return child_range(&Val, &Val+1); }
+ child_range children() { return child_range(&Val, &Val + 1); }
const_child_range children() const {
return const_child_range(&Val, &Val + 1);
}
@@ -1875,7 +1884,9 @@ class StringLiteral final
bool isUTF8() const { return getKind() == StringLiteralKind::UTF8; }
bool isUTF16() const { return getKind() == StringLiteralKind::UTF16; }
bool isUTF32() const { return getKind() == StringLiteralKind::UTF32; }
- bool isUnevaluated() const { return getKind() == StringLiteralKind::Unevaluated; }
+ bool isUnevaluated() const {
+ return getKind() == StringLiteralKind::Unevaluated;
+ }
bool isPascal() const { return StringLiteralBits.IsPascal; }
bool containsNonAscii() const {
@@ -2105,6 +2116,7 @@ class SYCLUniqueStableNameExpr final : public Expr {
class ParenExpr : public Expr {
SourceLocation L, R;
Stmt *Val;
+
public:
ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
: Expr(ParenExprClass, val->getType(), val->getValueKind(),
@@ -2114,8 +2126,7 @@ class ParenExpr : public Expr {
}
/// Construct an empty parenthesized expression.
- explicit ParenExpr(EmptyShell Empty)
- : Expr(ParenExprClass, Empty) { }
+ explicit ParenExpr(EmptyShell Empty) : Expr(ParenExprClass, Empty) {}
const Expr *getSubExpr() const { return cast<Expr>(Val); }
Expr *getSubExpr() { return cast<Expr>(Val); }
@@ -2137,7 +2148,7 @@ class ParenExpr : public Expr {
}
// Iterators
- child_range children() { return child_range(&Val, &Val+1); }
+ child_range children() { return child_range(&Val, &Val + 1); }
const_child_range children() const {
return const_child_range(&Val, &Val + 1);
}
@@ -2234,9 +2245,7 @@ class UnaryOperator final
}
/// isPrefix - Return true if this is a prefix operation, like --x.
- static bool isPrefix(Opcode Op) {
- return Op == UO_PreInc || Op == UO_PreDec;
- }
+ static bool isPrefix(Opcode Op) { return Op == UO_PreInc || Op == UO_PreDec; }
bool isPrefix() const { return isPrefix(getOpcode()); }
bool isPostfix() const { return isPostfix(getOpcode()); }
@@ -2244,16 +2253,12 @@ class UnaryOperator final
static bool isIncrementOp(Opcode Op) {
return Op == UO_PreInc || Op == UO_PostInc;
}
- bool isIncrementOp() const {
- return isIncrementOp(getOpcode());
- }
+ bool isIncrementOp() const { return isIncrementOp(getOpcode()); }
static bool isDecrementOp(Opcode Op) {
return Op == UO_PreDec || Op == UO_PostDec;
}
- bool isDecrementOp() const {
- return isDecrementOp(getOpcode());
- }
+ bool isDecrementOp() const { return isDecrementOp(getOpcode()); }
static bool isIncrementDecrementOp(Opcode Op) { return Op <= UO_PreDec; }
bool isIncrementDecrementOp() const {
@@ -2290,7 +2295,7 @@ class UnaryOperator final
}
// Iterators
- child_range children() { return child_range(&Val, &Val+1); }
+ child_range children() { return child_range(&Val, &Val + 1); }
const_child_range children() const {
return const_child_range(&Val, &Val + 1);
}
@@ -2450,24 +2455,22 @@ class OffsetOfExpr final
return NumComps;
}
- OffsetOfExpr(const ASTContext &C, QualType type,
- SourceLocation OperatorLoc, TypeSourceInfo *tsi,
- ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs,
- SourceLocation RParenLoc);
+ OffsetOfExpr(const ASTContext &C, QualType type, SourceLocation OperatorLoc,
+ TypeSourceInfo *tsi, ArrayRef<OffsetOfNode> comps,
+ ArrayRef<Expr *> exprs, SourceLocation RParenLoc);
explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
- : Expr(OffsetOfExprClass, EmptyShell()),
- TSInfo(nullptr), NumComps(numComps), NumExprs(numExprs) {}
+ : Expr(OffsetOfExprClass, EmptyShell()), TSInfo(nullptr),
+ NumComps(numComps), NumExprs(numExprs) {}
public:
-
static OffsetOfExpr *Create(const ASTContext &C, QualType type,
SourceLocation OperatorLoc, TypeSourceInfo *tsi,
ArrayRef<OffsetOfNode> comps,
- ...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff b17348c3b541d7fc7ec441c98db75c18d8959910 b256939140c99356f2ab41e2c69f3d218ffc81a6 -- clang/test/Sema/warn-compare-enum-types-mismatch.c clang/include/clang/AST/Expr.h clang/lib/AST/Expr.cpp clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaExpr.cpp clang/test/Sema/builtins-elementwise-math.c clang/test/Sema/warn-overlap.c clang/test/Sema/warn-conditional-enum-types-mismatch.c View the diff from clang-format here.diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2ccd8f5842..bfd8dbced1 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -9735,7 +9735,8 @@ ExprResult Sema::SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,
<< E->getSourceRange());
if (!DstTy->isVectorType() && !DstTy->isDependentType())
return ExprError(Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
- << "second" << "__builtin_convertvector");
+ << "second"
+ << "__builtin_convertvector");
if (!SrcTy->isDependentType() && !DstTy->isDependentType()) {
unsigned SrcElts = SrcTy->castAs<VectorType>()->getNumElements();
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index dbcd1513ed..cf2131c2f4 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4354,7 +4354,8 @@ static bool CheckVectorElementsTraitOperandType(Sema &S, QualType T,
// builtin_vectorelements supports both fixed-sized and scalable vectors.
if (!T->isVectorType() && !T->isSizelessVectorType())
return S.Diag(Loc, diag::err_builtin_non_vector_type)
- << "" << "__builtin_vectorelements" << T << ArgRange;
+ << ""
+ << "__builtin_vectorelements" << T << ArgRange;
return false;
}
|
Got the formatter wrong |
…C mode
Factored logic from
CheckImplicitConversion
into new methodsExpr::getEnumConstantDecl
andExpr::getEnumCoercedType
for use incheckEnumArithmeticConversions
.Fix #29217