diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-02-07 04:34:38 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-02-07 04:34:38 +0000 |
commit | 04ca25276245fbcf0a353e965de476080fa01b99 (patch) | |
tree | ac6a94fcc2e9a211258c5ba0ad7f0a2e9b9f890a /lib/Sema/SemaDecl.cpp | |
parent | 2ea020c8bbcc4ad18f35fd2c1edfea56ad44eae3 (diff) |
Fix a couple of nasty bugs involving negative enum constants. <rdar://problem/10760113>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149965 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 7f5bf1d633..c44b474e80 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -9600,23 +9600,6 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, &EnumVal).take())) { // C99 6.7.2.2p2: Make sure we have an integer constant expression. } else { - if (!getLangOptions().CPlusPlus) { - // C99 6.7.2.2p2: - // The expression that defines the value of an enumeration constant - // shall be an integer constant expression that has a value - // representable as an int. - - // Complain if the value is not representable in an int. - if (!isRepresentableIntegerValue(Context, EnumVal, Context.IntTy)) - Diag(IdLoc, diag::ext_enum_value_not_int) - << EnumVal.toString(10) << Val->getSourceRange() - << (EnumVal.isUnsigned() || EnumVal.isNonNegative()); - else if (!Context.hasSameType(Val->getType(), Context.IntTy)) { - // Force the type of the expression to 'int'. - Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take(); - } - } - if (Enum->isFixed()) { EltTy = Enum->getIntegerType(); @@ -9632,13 +9615,29 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, Diag(IdLoc, diag::err_enumerator_too_large) << EltTy; } else Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take(); - } else { + } else if (getLangOptions().CPlusPlus) { // C++11 [dcl.enum]p5: // If the underlying type is not fixed, the type of each enumerator // is the type of its initializing value: // - If an initializer is specified for an enumerator, the // initializing value has the same type as the expression. EltTy = Val->getType(); + } else { + // C99 6.7.2.2p2: + // The expression that defines the value of an enumeration constant + // shall be an integer constant expression that has a value + // representable as an int. + + // Complain if the value is not representable in an int. + if (!isRepresentableIntegerValue(Context, EnumVal, Context.IntTy)) + Diag(IdLoc, diag::ext_enum_value_not_int) + << EnumVal.toString(10) << Val->getSourceRange() + << (EnumVal.isUnsigned() || EnumVal.isNonNegative()); + else if (!Context.hasSameType(Val->getType(), Context.IntTy)) { + // Force the type of the expression to 'int'. + Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take(); + } + EltTy = Val->getType(); } } } @@ -9726,7 +9725,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, if (!EltTy->isDependentType()) { // Make the enumerator value match the signedness and size of the // enumerator's type. - EnumVal = EnumVal.zextOrTrunc(Context.getIntWidth(EltTy)); + EnumVal = EnumVal.extOrTrunc(Context.getIntWidth(EltTy)); EnumVal.setIsSigned(EltTy->isSignedIntegerOrEnumerationType()); } |