[cfe-commits] r149729 - in /cfe/trunk: lib/AST/ExprConstant.cpp lib/Sema/SemaDeclCXX.cpp test/SemaCXX/constexpr-sysheaders.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Fri Feb 3 16:33:54 PST 2012
Author: rsmith
Date: Fri Feb 3 18:33:54 2012
New Revision: 149729
URL: http://llvm.org/viewvc/llvm-project?rev=149729&view=rev
Log:
constexpr:
The recent support for potential constant expressions exposed a bug in the
implementation of libstdc++4.6, where numeric_limits<int>::min() is defined
as (int)1 << 31, which isn't a constant expression. Disable the 'constexpr
function never produces a constant expression' error inside system headers
to compensate.
Added:
cfe/trunk/test/SemaCXX/constexpr-sysheaders.cpp
Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=149729&r1=149728&r2=149729&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Feb 3 18:33:54 2012
@@ -575,7 +575,8 @@
static void describeCall(CallStackFrame *Frame, llvm::raw_ostream &Out) {
unsigned ArgIndex = 0;
bool IsMemberCall = isa<CXXMethodDecl>(Frame->Callee) &&
- !isa<CXXConstructorDecl>(Frame->Callee);
+ !isa<CXXConstructorDecl>(Frame->Callee) &&
+ cast<CXXMethodDecl>(Frame->Callee)->isInstance();
if (!IsMemberCall)
Out << *Frame->Callee << '(';
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=149729&r1=149728&r2=149729&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Feb 3 18:33:54 2012
@@ -838,13 +838,13 @@
/// \return true if the body is OK, false if we have diagnosed a problem.
bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) {
if (isa<CXXTryStmt>(Body)) {
- // C++0x [dcl.constexpr]p3:
+ // C++11 [dcl.constexpr]p3:
// The definition of a constexpr function shall satisfy the following
// constraints: [...]
// - its function-body shall be = delete, = default, or a
// compound-statement
//
- // C++0x [dcl.constexpr]p4:
+ // C++11 [dcl.constexpr]p4:
// In the definition of a constexpr constructor, [...]
// - its function-body shall not be a function-try-block;
Diag(Body->getLocStart(), diag::err_constexpr_function_try_block)
@@ -972,8 +972,23 @@
}
}
+ // C++11 [dcl.constexpr]p5:
+ // if no function argument values exist such that the function invocation
+ // substitution would produce a constant expression, the program is
+ // ill-formed; no diagnostic required.
+ // C++11 [dcl.constexpr]p3:
+ // - every constructor call and implicit conversion used in initializing the
+ // return value shall be one of those allowed in a constant expression.
+ // C++11 [dcl.constexpr]p4:
+ // - every constructor involved in initializing non-static data members and
+ // base class sub-objects shall be a constexpr constructor.
+ //
+ // FIXME: We currently disable this check inside system headers, to work
+ // around early STL implementations which contain constexpr functions which
+ // can't produce constant expressions.
llvm::SmallVector<PartialDiagnosticAt, 8> Diags;
- if (!Expr::isPotentialConstantExpr(Dcl, Diags)) {
+ if (!Context.getSourceManager().isInSystemHeader(Dcl->getLocation()) &&
+ !Expr::isPotentialConstantExpr(Dcl, Diags)) {
Diag(Dcl->getLocation(), diag::err_constexpr_function_never_constant_expr)
<< isa<CXXConstructorDecl>(Dcl);
for (size_t I = 0, N = Diags.size(); I != N; ++I)
Added: cfe/trunk/test/SemaCXX/constexpr-sysheaders.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constexpr-sysheaders.cpp?rev=149729&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/constexpr-sysheaders.cpp (added)
+++ cfe/trunk/test/SemaCXX/constexpr-sysheaders.cpp Fri Feb 3 18:33:54 2012
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -include %s %s
+
+// libstdc++4.6 has a broken numeric_limits with a non-constant min() for signed
+// integral types. Disable the 'never produces a constant expression' error in
+// system headers to work around it. We still won't treat the function as
+// producing a constant expression, though.
+
+#ifndef INCLUDED_HEADER
+#define INCLUDED_HEADER
+
+#pragma GCC system_header
+
+// An approximation of libstdc++4.6's broken definition of numeric_limits.
+// FIXME: In the -include case, the line numbers are off by one for some reason!
+struct numeric_limits { // expected-note {{value 2147483648 is outside the range}}
+ static constexpr int min() throw() { return (int)1 << (sizeof(int) * 8 - 1); } // no-error
+ // expected-note {{in call to 'min()'}}
+ static constexpr int lowest() throw() { return min(); }
+};
+
+#else
+
+constexpr int k = numeric_limits::lowest(); // expected-error {{constant expression}} expected-note {{in call to 'lowest()'}}
+
+#endif
More information about the cfe-commits
mailing list