[PATCH] D80925: Fix compiler crash when an expression parsed in the tentative parsing and must be claimed in the another evaluation context.
Alexey Bataev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 2 10:25:52 PDT 2020
ABataev updated this revision to Diff 267927.
ABataev added a comment.
Rebase + fixes
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D80925/new/
https://reviews.llvm.org/D80925
Files:
clang/include/clang/Basic/TokenKinds.def
clang/lib/Parse/ParseExpr.cpp
clang/lib/Parse/ParseTentative.cpp
clang/lib/Parse/Parser.cpp
clang/test/AST/alignas_maybe_odr_cleanup.cpp
Index: clang/test/AST/alignas_maybe_odr_cleanup.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/alignas_maybe_odr_cleanup.cpp
@@ -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
Index: clang/lib/Parse/Parser.cpp
===================================================================
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -1694,7 +1694,8 @@
}
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())
Index: clang/lib/Parse/ParseTentative.cpp
===================================================================
--- clang/lib/Parse/ParseTentative.cpp
+++ clang/lib/Parse/ParseTentative.cpp
@@ -1275,6 +1275,15 @@
// 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;
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -998,8 +998,23 @@
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);
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -742,6 +742,9 @@
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())"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D80925.267927.patch
Type: text/x-patch
Size: 4288 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200602/551b3b73/attachment.bin>
More information about the cfe-commits
mailing list