aaronpuchert created this revision. aaronpuchert added reviewers: aaron.ballman, riccibruno, rsmith. Herald added a subscriber: kristof.beyls. aaronpuchert requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The crash was introduced by D83183 <https://reviews.llvm.org/D83183> (f63e3ea558bb <https://reviews.llvm.org/rGf63e3ea558bbe14826b5b775367eac617b35e041>) as far as I can tell. The problem is that ParenListExprs have a <NULL TYPE> which the expression evaluation, specifically Expr::EvaluateAsInitializer, couldn't deal with. One solution would have been to make the evaluation logic capable of dealing with NULL TYPE, but I rather decided to harmonize ParenListExprs with InitListExprs, which always have a void type by default. Actually I think that the dependent type would not be a bad fit here: although the type of the contained expression might not be dependent, the type of the expression itself might be. But this seems like a bigger change, the assumption that InitListExprs have void type seems to be baked into quite a few places. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D98664 Files: clang/include/clang/AST/Expr.h clang/lib/AST/Expr.cpp clang/lib/Sema/SemaExpr.cpp clang/test/AST/ast-dump-expr-json.cpp clang/test/AST/ast-dump-expr.cpp clang/test/AST/ast-dump-lambda.cpp clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp clang/test/AST/ast-dump-recovery.cpp clang/test/AST/ast-dump-templates.cpp
Index: clang/test/AST/ast-dump-templates.cpp =================================================================== --- clang/test/AST/ast-dump-templates.cpp +++ clang/test/AST/ast-dump-templates.cpp @@ -67,3 +67,7 @@ template<typename T> A(T) -> A<int>; // CHECK1: template <typename T> A(T) -> A<int>; } + +template <typename T> constexpr T var(0); +// DUMP: VarDecl {{.*}} <col:23, col:40> col:35 var 'const T' constexpr callinit +// DUMP-NEXT: ParenListExpr {{.*}} <col:38, col:40> 'void' Index: clang/test/AST/ast-dump-recovery.cpp =================================================================== --- clang/test/AST/ast-dump-recovery.cpp +++ clang/test/AST/ast-dump-recovery.cpp @@ -173,7 +173,7 @@ // CHECK-NEDT: `-DeclRefExpr {{.*}} 'x' Bar a3{x}; // CHECK: `-VarDecl {{.*}} a4 'Bar' - // CHECK-NEXT: `-ParenListExpr {{.*}} 'NULL TYPE' contains-errors + // CHECK-NEXT: `-ParenListExpr {{.*}} contains-errors // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' Bar a4(invalid()); Index: clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp =================================================================== --- clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp +++ clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp @@ -115,7 +115,7 @@ // CHECK-NEXT: | | | `-VarDecl [[ADDR_45:0x[a-z0-9]*]] <col:3, col:10> col:10 referenced t 'double' // CHECK-NEXT: | | |-DeclStmt [[ADDR_46:0x[a-z0-9]*]] <line:19:3, col:16> // CHECK-NEXT: | | | `-VarDecl [[ADDR_47:0x[a-z0-9]*]] <col:3, col:15> col:8 q 'S<T>' callinit -// CHECK-NEXT: | | | `-ParenListExpr [[ADDR_48:0x[a-z0-9]*]] <col:9, col:15> 'NULL TYPE' +// CHECK-NEXT: | | | `-ParenListExpr [[ADDR_48:0x[a-z0-9]*]] <col:9, col:15> 'void' // CHECK-NEXT: | | | |-IntegerLiteral [[ADDR_49:0x[a-z0-9]*]] <col:10> 'int' 1 // CHECK-NEXT: | | | `-UnaryOperator [[ADDR_50:0x[a-z0-9]*]] <col:13, col:14> 'double *' prefix '&' cannot overflow // CHECK-NEXT: | | | `-DeclRefExpr [[ADDR_51:0x[a-z0-9]*]] <col:14> 'double' {{.*}}Var [[ADDR_45]] 't' 'double' @@ -150,7 +150,7 @@ // CHECK-NEXT: | | | `-VarDecl [[ADDR_73:0x[a-z0-9]*]] <col:3, col:5> col:5 referenced t 'T' // CHECK-NEXT: | | |-DeclStmt [[ADDR_74:0x[a-z0-9]*]] <line:25:3, col:16> // CHECK-NEXT: | | | `-VarDecl [[ADDR_75:0x[a-z0-9]*]] <col:3, col:15> col:8 q 'S<T>' callinit -// CHECK-NEXT: | | | `-ParenListExpr [[ADDR_76:0x[a-z0-9]*]] <col:9, col:15> 'NULL TYPE' +// CHECK-NEXT: | | | `-ParenListExpr [[ADDR_76:0x[a-z0-9]*]] <col:9, col:15> 'void' // CHECK-NEXT: | | | |-IntegerLiteral [[ADDR_77:0x[a-z0-9]*]] <col:10> 'int' 0 // CHECK-NEXT: | | | `-UnaryOperator [[ADDR_78:0x[a-z0-9]*]] <col:13, col:14> '<dependent type>' prefix '&' cannot overflow // CHECK-NEXT: | | | `-DeclRefExpr [[ADDR_79:0x[a-z0-9]*]] <col:14> 'T' {{.*}}Var [[ADDR_73]] 't' 'T' @@ -186,7 +186,7 @@ // CHECK-NEXT: | | `-VarDecl [[ADDR_102:0x[a-z0-9]*]] <col:3, col:10> col:10 referenced t 'double' // CHECK-NEXT: | |-DeclStmt [[ADDR_103:0x[a-z0-9]*]] <line:32:3, col:18> // CHECK-NEXT: | | `-VarDecl [[ADDR_104:0x[a-z0-9]*]] <col:3, col:17> col:8 q 'S<T>' callinit -// CHECK-NEXT: | | `-ParenListExpr [[ADDR_105:0x[a-z0-9]*]] <col:9, col:17> 'NULL TYPE' +// CHECK-NEXT: | | `-ParenListExpr [[ADDR_105:0x[a-z0-9]*]] <col:9, col:17> 'void' // CHECK-NEXT: | | |-FloatingLiteral [[ADDR_106:0x[a-z0-9]*]] <col:10> 'double' 2.000000e+00 // CHECK-NEXT: | | `-UnaryOperator [[ADDR_107:0x[a-z0-9]*]] <col:15, col:16> 'double *' prefix '&' cannot overflow // CHECK-NEXT: | | `-DeclRefExpr [[ADDR_108:0x[a-z0-9]*]] <col:16> 'double' {{.*}}Var [[ADDR_102]] 't' 'double' Index: clang/test/AST/ast-dump-lambda.cpp =================================================================== --- clang/test/AST/ast-dump-lambda.cpp +++ clang/test/AST/ast-dump-lambda.cpp @@ -65,7 +65,7 @@ // CHECK-NEXT: | | | |-CXXMethodDecl {{.*}} <col:12, col:15> col:7{{( imported)?}} operator() 'auto () const -> auto' inline // CHECK-NEXT: | | | | `-CompoundStmt {{.*}} <col:14, col:15> // CHECK-NEXT: | | | `-FieldDecl {{.*}} <col:8> col:8{{( imported)?}} implicit 'V *' -// CHECK-NEXT: | | |-ParenListExpr {{.*}} <col:8> 'NULL TYPE' +// CHECK-NEXT: | | |-ParenListExpr {{.*}} <col:8> 'void' // CHECK-NEXT: | | | `-CXXThisExpr {{.*}} <col:8> 'V *' this // CHECK-NEXT: | | `-CompoundStmt {{.*}} <col:14, col:15> // CHECK-NEXT: | `-LambdaExpr {{.*}} <line:19:7, col:16> '(lambda at {{.*}}ast-dump-lambda.cpp:19:7)' @@ -80,7 +80,7 @@ // CHECK-NEXT: | | |-CXXMethodDecl {{.*}} <col:13, col:16> col:7{{( imported)?}} operator() 'auto () const -> auto' inline // CHECK-NEXT: | | | `-CompoundStmt {{.*}} <col:15, col:16> // CHECK-NEXT: | | `-FieldDecl {{.*}} <col:8> col:8{{( imported)?}} implicit 'V' -// CHECK-NEXT: | |-ParenListExpr {{.*}} <col:8> 'NULL TYPE' +// CHECK-NEXT: | |-ParenListExpr {{.*}} <col:8> 'void' // CHECK-NEXT: | | `-UnaryOperator {{.*}} <col:8> '<dependent type>' prefix '*' cannot overflow // CHECK-NEXT: | | `-CXXThisExpr {{.*}} <col:8> 'V *' this // CHECK-NEXT: | `-CompoundStmt {{.*}} <col:15, col:16> @@ -129,7 +129,7 @@ // CHECK-NEXT: | | |-CXXMethodDecl {{.*}} <col:8, col:11> col:3{{( imported)?}} operator() 'auto () const -> auto' inline // CHECK-NEXT: | | | `-CompoundStmt {{.*}} <col:10, col:11> // CHECK-NEXT: | | `-FieldDecl {{.*}} <col:4> col:4{{( imported)?}} implicit 'Ts...' -// CHECK-NEXT: | |-ParenListExpr {{.*}} <col:4> 'NULL TYPE' +// CHECK-NEXT: | |-ParenListExpr {{.*}} <col:4> 'void' // CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:4> 'Ts' lvalue ParmVar {{.*}} 'a' 'Ts...' // CHECK-NEXT: | `-CompoundStmt {{.*}} <col:10, col:11> // CHECK-NEXT: |-LambdaExpr {{.*}} <line:26:3, col:8> '(lambda at {{.*}}ast-dump-lambda.cpp:26:3)' @@ -230,7 +230,7 @@ // CHECK-NEXT: | | | `-CompoundStmt {{.*}} <col:18, col:19> // CHECK-NEXT: | | |-FieldDecl {{.*}} <col:4> col:4{{( imported)?}} implicit 'Ts...' // CHECK-NEXT: | | `-FieldDecl {{.*}} <col:10> col:10{{( imported)?}} implicit 'int':'int' -// CHECK-NEXT: | |-ParenListExpr {{.*}} <col:4> 'NULL TYPE' +// CHECK-NEXT: | |-ParenListExpr {{.*}} <col:4> 'void' // CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:4> 'Ts' lvalue ParmVar {{.*}} 'a' 'Ts...' // CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:14> 'int' 12 // CHECK-NEXT: | `-CompoundStmt {{.*}} <col:18, col:19> Index: clang/test/AST/ast-dump-expr.cpp =================================================================== --- clang/test/AST/ast-dump-expr.cpp +++ clang/test/AST/ast-dump-expr.cpp @@ -280,7 +280,7 @@ // CHECK-NEXT: CXXMethodDecl // CHECK-NEXT: CompoundStmt // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:8> col:8 implicit 'V' - // CHECK-NEXT: ParenListExpr 0x{{[^ ]*}} <col:8> 'NULL TYPE' + // CHECK-NEXT: ParenListExpr 0x{{[^ ]*}} <col:8> 'void' // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:8> '<dependent type>' prefix '*' cannot overflow // CHECK-NEXT: CXXThisExpr 0x{{[^ ]*}} <col:8> 'V *' this } @@ -335,7 +335,7 @@ // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:8, col:10> col:3 operator() 'auto () const -> auto' inline // CHECK-NEXT: CompoundStmt // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:4> col:4 implicit 'Ts...' - // CHECK-NEXT: ParenListExpr 0x{{[^ ]*}} <col:4> 'NULL TYPE' + // CHECK-NEXT: ParenListExpr 0x{{[^ ]*}} <col:4> 'void' // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'Ts' lvalue ParmVar 0x{{[^ ]*}} 'a' 'Ts...' // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:9, col:10> @@ -448,7 +448,7 @@ // CHECK-NEXT: CompoundStmt // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:4> col:4 implicit 'Ts...' // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:10> col:10 implicit 'int':'int' - // CHECK-NEXT: ParenListExpr 0x{{[^ ]*}} <col:4> 'NULL TYPE' + // CHECK-NEXT: ParenListExpr 0x{{[^ ]*}} <col:4> 'void' // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'Ts' lvalue ParmVar 0x{{[^ ]*}} 'a' 'Ts...' // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:14> 'int' 12 // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:17, col:18> Index: clang/test/AST/ast-dump-expr-json.cpp =================================================================== --- clang/test/AST/ast-dump-expr-json.cpp +++ clang/test/AST/ast-dump-expr-json.cpp @@ -4036,7 +4036,7 @@ // CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "NULL TYPE" +// CHECK-NEXT: "qualType": "void" // CHECK-NEXT: }, // CHECK-NEXT: "valueCategory": "rvalue", // CHECK-NEXT: "inner": [ @@ -4247,7 +4247,7 @@ // CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "NULL TYPE" +// CHECK-NEXT: "qualType": "void" // CHECK-NEXT: }, // CHECK-NEXT: "valueCategory": "rvalue", // CHECK-NEXT: "inner": [ @@ -5022,7 +5022,7 @@ // CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "NULL TYPE" +// CHECK-NEXT: "qualType": "void" // CHECK-NEXT: }, // CHECK-NEXT: "valueCategory": "rvalue", // CHECK-NEXT: "inner": [ @@ -6602,7 +6602,7 @@ // CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "NULL TYPE" +// CHECK-NEXT: "qualType": "void" // CHECK-NEXT: }, // CHECK-NEXT: "valueCategory": "rvalue", // CHECK-NEXT: "inner": [ Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -7021,10 +7021,7 @@ } } - InitListExpr *E = new (Context) InitListExpr(Context, LBraceLoc, InitArgList, - RBraceLoc); - E->setType(Context.VoidTy); // FIXME: just a place holder for now. - return E; + return new (Context) InitListExpr(Context, LBraceLoc, InitArgList, RBraceLoc); } /// Do an explicit extend of the given block pointer if we're in ARC. Index: clang/lib/AST/Expr.cpp =================================================================== --- clang/lib/AST/Expr.cpp +++ clang/lib/AST/Expr.cpp @@ -2105,7 +2105,7 @@ InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc, ArrayRef<Expr *> initExprs, SourceLocation rbraceloc) - : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary), + : Expr(InitListExprClass, QualType(C.VoidTy), VK_RValue, OK_Ordinary), InitExprs(C, initExprs.size()), LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(nullptr, true) { sawArrayRangeDesignator(false); @@ -4289,9 +4289,9 @@ return getBase()->getEndLoc(); } -ParenListExpr::ParenListExpr(SourceLocation LParenLoc, ArrayRef<Expr *> Exprs, - SourceLocation RParenLoc) - : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary), +ParenListExpr::ParenListExpr(const ASTContext &C, SourceLocation LParenLoc, + ArrayRef<Expr *> Exprs, SourceLocation RParenLoc) + : Expr(ParenListExprClass, QualType(C.VoidTy), VK_RValue, OK_Ordinary), LParenLoc(LParenLoc), RParenLoc(RParenLoc) { ParenListExprBits.NumExprs = Exprs.size(); @@ -4311,7 +4311,7 @@ SourceLocation RParenLoc) { void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(Exprs.size()), alignof(ParenListExpr)); - return new (Mem) ParenListExpr(LParenLoc, Exprs, RParenLoc); + return new (Mem) ParenListExpr(Ctx, LParenLoc, Exprs, RParenLoc); } ParenListExpr *ParenListExpr::CreateEmpty(const ASTContext &Ctx, Index: clang/include/clang/AST/Expr.h =================================================================== --- clang/include/clang/AST/Expr.h +++ clang/include/clang/AST/Expr.h @@ -5463,8 +5463,8 @@ SourceLocation LParenLoc, RParenLoc; /// Build a paren list. - ParenListExpr(SourceLocation LParenLoc, ArrayRef<Expr *> Exprs, - SourceLocation RParenLoc); + ParenListExpr(const ASTContext &C, SourceLocation LParenLoc, + ArrayRef<Expr *> Exprs, SourceLocation RParenLoc); /// Build an empty paren list. ParenListExpr(EmptyShell Empty, unsigned NumExprs);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits