forked from OSchip/llvm-project
When checking whether a reference to a variable is an ICE, look at the type of
the declaration, not at the type of the DeclRefExpr, since within a lambda the DeclRefExpr can be more const than the declaration is. llvm-svn: 151399
This commit is contained in:
parent
9fceb90175
commit
6365c9138e
|
@ -6379,12 +6379,12 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
|
|||
return CheckEvalInICE(E, Ctx);
|
||||
return ICEDiag(2, E->getLocStart());
|
||||
}
|
||||
case Expr::DeclRefExprClass:
|
||||
case Expr::DeclRefExprClass: {
|
||||
if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
|
||||
return NoDiag();
|
||||
if (Ctx.getLangOptions().CPlusPlus && IsConstNonVolatile(E->getType())) {
|
||||
const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl();
|
||||
|
||||
const ValueDecl *D = dyn_cast<ValueDecl>(cast<DeclRefExpr>(E)->getDecl());
|
||||
if (Ctx.getLangOptions().CPlusPlus &&
|
||||
D && IsConstNonVolatile(D->getType())) {
|
||||
// Parameter variables are never constants. Without this check,
|
||||
// getAnyInitializer() can find a default argument, which leads
|
||||
// to chaos.
|
||||
|
@ -6408,6 +6408,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
|
|||
}
|
||||
}
|
||||
return ICEDiag(2, E->getLocStart());
|
||||
}
|
||||
case Expr::UnaryOperatorClass: {
|
||||
const UnaryOperator *Exp = cast<UnaryOperator>(E);
|
||||
switch (Exp->getOpcode()) {
|
||||
|
|
|
@ -101,3 +101,30 @@ namespace PR12031 {
|
|||
f(v, [](){});
|
||||
}
|
||||
}
|
||||
|
||||
namespace NullPtr {
|
||||
int &f(int *p);
|
||||
char &f(...);
|
||||
void g() {
|
||||
int n = 0;
|
||||
[=] {
|
||||
char &k = f(n); // not a null pointer constant
|
||||
} ();
|
||||
|
||||
const int m = 0;
|
||||
[=] {
|
||||
int &k = f(m); // a null pointer constant
|
||||
} ();
|
||||
|
||||
// FIXME: At least the second of these cases should probably not be
|
||||
// considered to be a null pointer constant.
|
||||
[=] () -> bool {
|
||||
int &k = f(m); // a null pointer constant?
|
||||
return &m == 0; // no, captured!
|
||||
} ();
|
||||
|
||||
[m] {
|
||||
int &k = f(m); // a null pointer constant?
|
||||
} ();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue