ABataev updated this revision to Diff 267743. ABataev added a comment. Reworked after comments.
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,11 @@ // 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); + // Enter unevaluated context to prevent propagation of the odr-use data to + // outer context in case of unsuccesful tentative parsing. + 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,19 @@ 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()) { + 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())"
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,11 @@ // 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); + // Enter unevaluated context to prevent propagation of the odr-use data to + // outer context in case of unsuccesful tentative parsing. + 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,19 @@ 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()) { + 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())"
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits