forked from OSchip/llvm-project
Fix compiler crash when an expression parsed in the tentative parsing and must be claimed in the another evaluation context.
Summary: Clang crashes when trying to finish function body. MaybeODRUseExprs is not empty because of const static data member parsed in outer evaluation context, upon call for isTypeIdInParens() function. It builds annot_primary_expr, later parsed in ParseConstantExpression() in inner constant expression evaluation context. Reviewers: rjmccall, rsmith Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D80925
This commit is contained in:
parent
b78b98491a
commit
2f7269b677
|
@ -742,6 +742,9 @@ ANNOTATION(non_type_undeclared) // annotation for an undeclared identifier that
|
|||
ANNOTATION(non_type_dependent) // annotation for an assumed non-type member of
|
||||
// a dependent base class
|
||||
ANNOTATION(primary_expr) // annotation for a primary expression
|
||||
ANNOTATION(
|
||||
uneval_primary_expr) // annotation for a primary expression which should be
|
||||
// transformed to potentially evaluated
|
||||
ANNOTATION(decltype) // annotation for a decltype expression,
|
||||
// e.g., "decltype(foo.bar())"
|
||||
|
||||
|
|
|
@ -998,8 +998,23 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
|
|||
Diag(Tok, diag::warn_cxx98_compat_nullptr);
|
||||
return Actions.ActOnCXXNullPtrLiteral(ConsumeToken());
|
||||
|
||||
case tok::annot_uneval_primary_expr:
|
||||
case tok::annot_primary_expr:
|
||||
Res = getExprAnnotation(Tok);
|
||||
if (SavedKind == tok::annot_uneval_primary_expr) {
|
||||
if (Expr *E = Res.get()) {
|
||||
if (!E->isTypeDependent() && !E->containsErrors()) {
|
||||
// TransformToPotentiallyEvaluated expects that it will still be in a
|
||||
// (temporary) unevaluated context and then looks through that context
|
||||
// to build it in the surrounding context. So we need to push an
|
||||
// unevaluated context to balance things out.
|
||||
EnterExpressionEvaluationContext Unevaluated(
|
||||
Actions, Sema::ExpressionEvaluationContext::Unevaluated,
|
||||
Sema::ReuseLambdaContextDecl);
|
||||
Res = Actions.TransformToPotentiallyEvaluated(Res.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
ConsumeAnnotationToken();
|
||||
if (!Res.isInvalid() && Tok.is(tok::less))
|
||||
checkPotentialAngleBracket(Res);
|
||||
|
|
|
@ -1275,6 +1275,15 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
|||
// this is ambiguous. Typo-correct to type and expression keywords and
|
||||
// to types and identifiers, in order to try to recover from errors.
|
||||
TentativeParseCCC CCC(Next);
|
||||
// Tentative parsing may not be done in the right evaluation context
|
||||
// for the ultimate expression. Enter an unevaluated context to prevent
|
||||
// Sema from immediately e.g. treating this lookup as a potential ODR-use.
|
||||
// If we generate an expression annotation token and the parser actually
|
||||
// claims it as an expression, we'll transform the expression to a
|
||||
// potentially-evaluated one then.
|
||||
EnterExpressionEvaluationContext Unevaluated(
|
||||
Actions, Sema::ExpressionEvaluationContext::Unevaluated,
|
||||
Sema::ReuseLambdaContextDecl);
|
||||
switch (TryAnnotateName(&CCC)) {
|
||||
case ANK_Error:
|
||||
return TPResult::Error;
|
||||
|
|
|
@ -1694,7 +1694,8 @@ Parser::TryAnnotateName(CorrectionCandidateCallback *CCC) {
|
|||
}
|
||||
|
||||
case Sema::NC_ContextIndependentExpr:
|
||||
Tok.setKind(tok::annot_primary_expr);
|
||||
Tok.setKind(Actions.isUnevaluatedContext() ? tok::annot_uneval_primary_expr
|
||||
: tok::annot_primary_expr);
|
||||
setExprAnnotation(Tok, Classification.getExpression());
|
||||
Tok.setAnnotationEndLoc(NameLoc);
|
||||
if (SS.isNotEmpty())
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only %s -ast-dump | FileCheck %s
|
||||
|
||||
struct FOO {
|
||||
static const int vec_align_bytes = 32;
|
||||
void foo() {
|
||||
double a alignas(vec_align_bytes);
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
// CHECK: AlignedAttr {{.*}} alignas
|
||||
// CHECK: ConstantExpr {{.+}} 'int' Int: 32
|
||||
// CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
|
||||
// CHECK: DeclRefExpr {{.*}} 'const int' lvalue Var {{.*}} 'vec_align_bytes' 'const int' non_odr_use_constant
|
||||
// CHECK: NullStmt
|
Loading…
Reference in New Issue