From 986cbd80d1dc838c61abff24b8d7ac28dcf4ac2a Mon Sep 17 00:00:00 2001 From: Takuya Shimizu Date: Tue, 23 May 2023 00:29:20 +0900 Subject: [PATCH] [clang][AST] TextNodeDumper should not evaluate the initializer of constexpr variable declaration when it has a dependent type `TextNodeDumper` enabed through `-ast-dump` flag should not evlauate the initializer when it visits a constexpr `VarDecl` node if it has a dependent type. I found a crashing case fixed by this change and added it as a test case. `template constexpr T call_init(0);` Link: https://godbolt.org/z/3bG9Pjj5E This is a fix for the regression caused by D146358 Differential Revision: https://reviews.llvm.org/D151033 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/AST/TextNodeDumper.cpp | 3 ++- clang/test/AST/ast-dump-decl.cpp | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c80cc89..a55e969 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -420,6 +420,8 @@ Bug Fixes in This Version (`#62711 `_). - Fix crash on attempt to initialize union with flexible array member. (`#61746 `_). +- Clang `TextNodeDumper` enabled through `-ast-dump` flag no longer evaluates the + initializer of constexpr `VarDecl` if the declaration has a dependent type. Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 3817025..b89a13d 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1821,7 +1821,8 @@ void TextNodeDumper::VisitVarDecl(const VarDecl *D) { if (D->hasInit()) { const Expr *E = D->getInit(); // Only dump the value of constexpr VarDecls for now. - if (E && !E->isValueDependent() && D->isConstexpr()) { + if (E && !E->isValueDependent() && D->isConstexpr() && + !D->getType()->isDependentType()) { const APValue *Value = D->evaluateValue(); if (Value) AddChild("value", [=] { Visit(*Value, E->getType()); }); diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp index 3be99c9..276a209 100644 --- a/clang/test/AST/ast-dump-decl.cpp +++ b/clang/test/AST/ast-dump-decl.cpp @@ -818,3 +818,38 @@ namespace Comment { // CHECK: `-TextComment // CHECK: VarDecl {{.*}} Test 'int' extern // CHECK-NOT: FullComment + +namespace TestConstexprVariableTemplateWithInitializer { + template constexpr T foo{}; + // CHECK: VarTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-1]]:3, col:40> col:36 foo + // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 referenced typename depth 0 index 0 T + // CHECK-NEXT: `-VarDecl 0x{{.+}} col:36 foo 'const T' constexpr listinit + // CHECK-NEXT: `-InitListExpr 0x{{.+}} 'void' + + template constexpr int val{42}; + // CHECK: VarTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-1]]:3, col:44> col:38 val + // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T + // CHECK-NEXT: `-VarDecl 0x{{.+}} col:38 val 'const int' constexpr listinit + // CHECK-NEXT: |-value: Int 42 + // CHECK-NEXT: `-InitListExpr 0x{{.+}} 'int' + + template + struct in_place_type_t { + explicit in_place_type_t() = default; + }; + + template + inline constexpr in_place_type_t<_Tp> in_place_type{}; + // CHECK: -VarTemplateDecl 0x{{.+}} col:41 in_place_type + // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:22 referenced typename depth 0 index 0 _Tp + // CHECK-NEXT: `-VarDecl 0x{{.+}} col:41 in_place_type 'const in_place_type_t<_Tp>':'const in_place_type_t<_Tp>' inline constexpr listinit + // CHECK-NEXT: `-InitListExpr 0x{{.+}} 'void' + + template constexpr T call_init(0); + // CHECK: -VarTemplateDecl 0x{{.+}} col:37 call_init + // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:22 referenced typename depth 0 index 0 T + // CHECK-NEXT: `-VarDecl 0x{{.+}} col:37 call_init 'const T' constexpr callinit + // CHECK-NEXT: `-ParenListExpr 0x{{.+}} 'NULL TYPE' + // CHECK-NEXT: `-IntegerLiteral 0x{{.+}} 'int' 0 + +} -- 2.7.4