forked from OSchip/llvm-project
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:
parent
c88e40450d
commit
f86b5dc700
|
@ -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<
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue