diff options
| author | Chris Lattner <sabre@nondot.org> | 2011-06-14 05:46:29 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2011-06-14 05:46:29 +0000 |
| commit | 9925ec8bf44688f7e529f4c143d2d0933919b4a7 (patch) | |
| tree | 6e351656e04d646eeb5b3bfc7355eab1e226f139 /clang | |
| parent | c75d1a10985a949307ece6432c3b7248597314ed (diff) | |
| download | bcm5719-llvm-9925ec8bf44688f7e529f4c143d2d0933919b4a7.tar.gz bcm5719-llvm-9925ec8bf44688f7e529f4c143d2d0933919b4a7.zip | |
fix rdar://9204520 - Accept int(0.85 * 10) as an initializer in a class member
as an extension.
llvm-svn: 132980
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 26 | ||||
| -rw-r--r-- | clang/test/SemaCXX/i-c-e-cxx.cpp | 13 |
3 files changed, 33 insertions, 9 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index d64817b4eed..c765deb8e6b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3542,6 +3542,9 @@ def ext_in_class_initializer_float_type : ExtWarn< def err_in_class_initializer_non_constant : Error< "in-class initializer is not a constant expression">; +def ext_in_class_initializer_non_constant : Extension< + "in-class initializer is not a constant expression, accepted as an extension">; + // C++ anonymous unions and GNU anonymous structs/unions def ext_anonymous_union : Extension< "anonymous unions are a GNU extension in C">, InGroup<GNU>; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a308892c531..49e59c76aa8 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5369,15 +5369,23 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // We allow integer constant expressions in all cases. } else if (T->isIntegralOrEnumerationType()) { - if (!Init->isValueDependent()) { - // Check whether the expression is a constant expression. - llvm::APSInt Value; - SourceLocation Loc; - if (!Init->isIntegerConstantExpr(Value, Context, &Loc)) { - Diag(Loc, diag::err_in_class_initializer_non_constant) - << Init->getSourceRange(); - VDecl->setInvalidDecl(); - } + // Check whether the expression is a constant expression. + SourceLocation Loc; + if (Init->isValueDependent()) + ; // Nothing to check. + else if (Init->isIntegerConstantExpr(Context, &Loc)) + ; // Ok, it's an ICE! + else if (Init->isEvaluatable(Context)) { + // If we can constant fold the initializer through heroics, accept it, + // but report this as a use of an extension for -pedantic. + Diag(Loc, diag::ext_in_class_initializer_non_constant) + << Init->getSourceRange(); + } else { + // Otherwise, this is some crazy unknown case. Report the issue at the + // location provided by the isIntegerConstantExpr failed check. + Diag(Loc, diag::err_in_class_initializer_non_constant) + << Init->getSourceRange(); + VDecl->setInvalidDecl(); } // We allow floating-point constants as an extension in C++03, and diff --git a/clang/test/SemaCXX/i-c-e-cxx.cpp b/clang/test/SemaCXX/i-c-e-cxx.cpp index 2d08ea9a428..186e32126a3 100644 --- a/clang/test/SemaCXX/i-c-e-cxx.cpp +++ b/clang/test/SemaCXX/i-c-e-cxx.cpp @@ -42,3 +42,16 @@ namespace pr6206 { void pr6373(const unsigned x = 0) { unsigned max = 80 / x; } + + +// rdar://9204520 +namespace rdar9204520 { + +struct A { + static const int B = int(0.75 * 1000 * 1000); +}; + +int foo() { return A::B; } +} + + |

