PR14550: If a system header contains a bogus constexpr function definition,

don't mark the function as invalid, since we suppress the error.

llvm-svn: 169689
This commit is contained in:
Richard Smith 2012-12-09 05:55:43 +00:00
parent c88e40450d
commit f86b5dc700
3 changed files with 25 additions and 4 deletions

View File

@ -1538,7 +1538,7 @@ def err_constexpr_vla : Error<
"%select{function|constructor}1">;
def err_constexpr_var_declaration : Error<
"variables cannot be declared in a constexpr %select{function|constructor}0">;
def err_constexpr_function_never_constant_expr : ExtWarn<
def ext_constexpr_function_never_constant_expr : ExtWarn<
"constexpr %select{function|constructor}0 never produces a "
"constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError;
def err_constexpr_body_no_return : Error<

View File

@ -994,11 +994,12 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) {
// base class sub-objects shall be a constexpr constructor.
llvm::SmallVector<PartialDiagnosticAt, 8> Diags;
if (!Expr::isPotentialConstantExpr(Dcl, Diags)) {
Diag(Dcl->getLocation(), diag::err_constexpr_function_never_constant_expr)
Diag(Dcl->getLocation(), diag::ext_constexpr_function_never_constant_expr)
<< isa<CXXConstructorDecl>(Dcl);
for (size_t I = 0, N = Diags.size(); I != N; ++I)
Diag(Diags[I].first, Diags[I].second);
return false;
// Don't return false here: we allow this for compatibility in
// system headers.
}
return true;

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown -verify -std=c++11 -fcxx-exceptions %s
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown -std=c++11 -fcxx-exceptions -Wno-invalid-constexpr %s
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown -std=c++11 -fcxx-exceptions -Wno-invalid-constexpr %s -DNO_INVALID_CONSTEXPR
namespace StdExample {
@ -110,3 +110,23 @@ int y1 = Y<int>().get(); // ok
int y2 = Y<Z>().get(); // ok
}
#ifndef NO_INVALID_CONSTEXPR
namespace PR14550 {
// As an "extension", we allow functions which can't produce constant
// expressions to be declared constexpr in system headers (libstdc++
// marks some functions as constexpr which use builtins which we don't
// support constant folding). Ensure that we don't mark those functions
// as invalid after suppressing the diagnostic.
# 122 "p5.cpp" 1 3
int n;
struct A {
static constexpr int f() { return n; }
};
template<typename T> struct B {
B() { g(T::f()); } // expected-error {{undeclared identifier 'g'}}
};
# 130 "p5.cpp" 2
template class B<A>; // expected-note {{here}}
}
#endif