From 48a1e81715bf9c37a4168d83f4218e6517e29541 Mon Sep 17 00:00:00 2001 From: Joey Gouly Date: Thu, 6 Jun 2013 13:48:00 +0000 Subject: [PATCH] Fix a crash with -Wassign-enum, where we didn't adjust the APInt type of the constant. Also fix some spelling mistakes and formatting issues. Reviewed by Richard Smith over IRC. Fixes PR15069. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183409 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 +- lib/Sema/SemaStmt.cpp | 21 +++++++++++---------- test/Sema/warn-outof-range-assign-enum.c | 12 ++++++++++++ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 32abf8a2a7..c328e71057 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -6073,7 +6073,7 @@ def warn_unreachable_default : Warning< InGroup, DefaultIgnore; def warn_not_in_enum : Warning<"case value not in enumerated type %0">, InGroup; -def warn_not_in_enum_assignement : Warning<"integer constant not in range " +def warn_not_in_enum_assignment : Warning<"integer constant not in range " "of enumerated type %0">, InGroup>, DefaultIgnore; def err_typecheck_statement_requires_scalar : Error< "statement requires expression of scalar type (%0 invalid)">; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index a6b98a2f6a..7c2ee9dbe7 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1120,9 +1120,9 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, void Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, Expr *SrcExpr) { - unsigned DIAG = diag::warn_not_in_enum_assignement; - if (Diags.getDiagnosticLevel(DIAG, SrcExpr->getExprLoc()) - == DiagnosticsEngine::Ignored) + if (Diags.getDiagnosticLevel(diag::warn_not_in_enum_assignment, + SrcExpr->getExprLoc()) == + DiagnosticsEngine::Ignored) return; if (const EnumType *ET = DstType->getAs()) @@ -1131,13 +1131,14 @@ Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, if (!SrcExpr->isTypeDependent() && !SrcExpr->isValueDependent() && SrcExpr->isIntegerConstantExpr(Context)) { // Get the bitwidth of the enum value before promotions. - unsigned DstWith = Context.getIntWidth(DstType); + unsigned DstWidth = Context.getIntWidth(DstType); bool DstIsSigned = DstType->isSignedIntegerOrEnumerationType(); llvm::APSInt RhsVal = SrcExpr->EvaluateKnownConstInt(Context); + AdjustAPSInt(RhsVal, DstWidth, DstIsSigned); const EnumDecl *ED = ET->getDecl(); - typedef SmallVector, 64> - EnumValsTy; + typedef SmallVector, 64> + EnumValsTy; EnumValsTy EnumVals; // Gather all enum values, set their type and sort them, @@ -1145,21 +1146,21 @@ Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(); EDI != ED->enumerator_end(); ++EDI) { llvm::APSInt Val = EDI->getInitVal(); - AdjustAPSInt(Val, DstWith, DstIsSigned); + AdjustAPSInt(Val, DstWidth, DstIsSigned); EnumVals.push_back(std::make_pair(Val, *EDI)); } if (EnumVals.empty()) return; std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals); EnumValsTy::iterator EIend = - std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals); + std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals); - // See which case values aren't in enum. + // See which values aren't in the enum. EnumValsTy::const_iterator EI = EnumVals.begin(); while (EI != EIend && EI->first < RhsVal) EI++; if (EI == EIend || EI->first != RhsVal) { - Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignement) + Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment) << DstType; } } diff --git a/test/Sema/warn-outof-range-assign-enum.c b/test/Sema/warn-outof-range-assign-enum.c index 2e79e66f49..43eea0cef4 100644 --- a/test/Sema/warn-outof-range-assign-enum.c +++ b/test/Sema/warn-outof-range-assign-enum.c @@ -21,6 +21,18 @@ enum Test2 test2(enum Test2 *t) { return 10; // expected-warning {{integer constant not in range of enumerated type 'enum Test2'}} } +// PR15069 +typedef enum +{ + a = 0 +} T; + +void f() +{ + T x = a; + x += 1; // expected-warning {{integer constant not in range of enumerated type}} +} + int main() { CCTestEnum test = 1; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}} test = 600; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}} -- 2.40.0