From: Chris Lattner Date: Tue, 28 Aug 2007 05:27:00 +0000 (+0000) Subject: add a diagnostic: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=211a30e92837fb32199d0c2700246b0c7cba5543;p=clang add a diagnostic: t.c:1:12: warning: ISO C restricts enumerator values to range of 'int' (180388626432 is too large) enum e {A, B = 42LL << 32, C = -4, D = 12456 }; ^ git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41530 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 5ab40ec28f..301813bb18 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -987,6 +987,7 @@ void Sema::ParseEnumBody(SourceLocation EnumLoc, DeclTy *EnumDeclX, // TODO: If the result value doesn't fit in an int, it must be a long or long // long value. ISO C does not support this, but GCC does as an extension, // emit a warning. + unsigned IntWidth = Context.getTypeSize(Context.IntTy, Enum->getLocation()); // Verify that all the values are okay, and reverse the list. @@ -995,6 +996,19 @@ void Sema::ParseEnumBody(SourceLocation EnumLoc, DeclTy *EnumDeclX, EnumConstantDecl *ECD = cast_or_null(static_cast(Elements[i])); if (!ECD) continue; // Already issued a diagnostic. + + // If the enum value doesn't fit in an int, emit an extension warning. + assert(ECD->getInitVal().getBitWidth() >= IntWidth && + "Should have promoted value to int"); + const llvm::APSInt &InitVal = ECD->getInitVal(); + if (InitVal.getBitWidth() > IntWidth) { + llvm::APSInt V(InitVal); + V.trunc(IntWidth); + V.extend(InitVal.getBitWidth()); + if (V != InitVal) + Diag(ECD->getLocation(), diag::ext_enum_value_not_int, + InitVal.toString()); + } ECD->setNextDeclarator(EltList); EltList = ECD; diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index d77fb77fa8..616889c3a8 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -520,6 +520,8 @@ DIAG(err_duplicate_member, ERROR, "duplicate member '%0'") DIAG(err_enum_value_not_integer_constant_expr, ERROR, "enumerator value for '%0' is not an integer constant") +DIAG(ext_enum_value_not_int, EXTENSION, + "ISO C restricts enumerator values to range of 'int' (%0 is too large)") DIAG(err_case_label_not_integer_constant_expr, ERROR, "case label does not reduce to an integer constant") DIAG(err_typecheck_illegal_vla, ERROR,