-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[clang][Sema] Fix initialization of NonTypeTemplateParmDecl...
#121768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
da2bbf9
fc14083
ab1616f
12d918f
792fb35
869eae8
38d144e
5805f98
d343d5e
cfd9d69
5bf0d70
786d7bd
b51566b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1235,15 +1235,24 @@ bool Sema::AttachTypeConstraint(AutoTypeLoc TL, | |
| << NewConstrainedParm->getTypeSourceInfo() | ||
| ->getTypeLoc() | ||
| .getSourceRange(); | ||
| NewConstrainedParm->setPlaceholderTypeConstraint( | ||
| RecoveryExpr::Create(Context, OrigConstrainedParm->getType(), | ||
| OrigConstrainedParm->getBeginLoc(), | ||
| OrigConstrainedParm->getEndLoc(), {})); | ||
| return true; | ||
| } | ||
| // FIXME: Concepts: This should be the type of the placeholder, but this is | ||
| // unclear in the wording right now. | ||
| DeclRefExpr *Ref = | ||
| BuildDeclRefExpr(OrigConstrainedParm, OrigConstrainedParm->getType(), | ||
| VK_PRValue, OrigConstrainedParm->getLocation()); | ||
| if (!Ref) | ||
| if (!Ref) { | ||
| NewConstrainedParm->setPlaceholderTypeConstraint( | ||
| RecoveryExpr::Create(Context, OrigConstrainedParm->getType(), | ||
| OrigConstrainedParm->getBeginLoc(), | ||
| OrigConstrainedParm->getEndLoc(), {})); | ||
|
||
| return true; | ||
| } | ||
| ExprResult ImmediatelyDeclaredConstraint = formImmediatelyDeclaredConstraint( | ||
| *this, TL.getNestedNameSpecifierLoc(), TL.getConceptNameInfo(), | ||
| TL.getNamedConcept(), /*FoundDecl=*/TL.getFoundDecl(), TL.getLAngleLoc(), | ||
|
|
@@ -1255,8 +1264,13 @@ bool Sema::AttachTypeConstraint(AutoTypeLoc TL, | |
| }, | ||
| EllipsisLoc); | ||
| if (ImmediatelyDeclaredConstraint.isInvalid() || | ||
| !ImmediatelyDeclaredConstraint.isUsable()) | ||
| !ImmediatelyDeclaredConstraint.isUsable()) { | ||
| NewConstrainedParm->setPlaceholderTypeConstraint( | ||
| RecoveryExpr::Create(Context, OrigConstrainedParm->getType(), | ||
|
||
| OrigConstrainedParm->getBeginLoc(), | ||
| OrigConstrainedParm->getEndLoc(), {})); | ||
|
||
| return true; | ||
| } | ||
|
|
||
| NewConstrainedParm->setPlaceholderTypeConstraint( | ||
| ImmediatelyDeclaredConstraint.get()); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| // RUN: rm -rf %t | ||
| // RUN: split-file %s %t | ||
| // RUN: cd %t | ||
|
|
||
| // RUN: %clang_cc1 -std=c++20 mod.cppm -emit-module-interface -o mod.pcm -fallow-pcm-with-compiler-errors -verify | ||
| // RUN: %clang_cc1 -std=c++20 main.cpp -fmodule-file=mod=mod.pcm -verify -fallow-pcm-with-compiler-errors -fsyntax-only -ast-dump-all | FileCheck %s | ||
|
Comment on lines
+5
to
+6
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if this also manifests with just pch serialization - it would always be great if we can simplify the test
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't even need serialization. IIRC it can be triggered with an ast dump, but only if the uninitialized value happens not to be a 0, which is the tricky part to trigger (not using sanitizers, that is). |
||
|
|
||
| //--- mod.cppm | ||
| export module mod; | ||
|
|
||
| template <typename T, auto Q> | ||
| concept ReferenceOf = Q; | ||
|
|
||
| // expected-error@+2 {{unknown type name 'AngleIsInvalidNow'}} | ||
| // expected-error@+1 {{constexpr variable 'angle' must be initialized by a constant expression}} | ||
| constexpr struct angle {AngleIsInvalidNow e;} angle; | ||
|
|
||
| // expected-error@+1 {{non-type template argument is not a constant expression}} | ||
| template<ReferenceOf<angle> auto R, typename Rep> requires requires(Rep v) {cos(v);} | ||
| auto cos(const Rep& q); | ||
|
|
||
| // expected-error@+1 {{non-type template argument is not a constant expression}} | ||
| template<ReferenceOf<angle> auto R, typename Rep> requires requires(Rep v) {tan(v);} | ||
| auto tan(const Rep& q); | ||
|
|
||
| //--- main.cpp | ||
| // expected-no-diagnostics | ||
| import mod; | ||
|
|
||
| // CHECK: |-FunctionTemplateDecl {{.*}} <line:11:1, line:12:22> col:6 imported in mod hidden invalid cos | ||
| // CHECK-NEXT: | |-NonTypeTemplateParmDecl {{.*}} <line:11:10, col:34> col:34 imported in mod hidden referenced invalid 'ReferenceOf<angle> auto' depth 0 index 0 R | ||
| // CHECK-NEXT: | | `-RecoveryExpr {{.*}} <col:10, col:34> 'ReferenceOf<angle> auto' contains-errors lvalue | ||
| // CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} <col:37, col:46> col:46 imported in mod hidden referenced typename depth 0 index 1 Rep | ||
| // CHECK-NEXT: | |-RequiresExpr {{.*}} <col:60, col:84> 'bool' | ||
| // CHECK-NEXT: | | |-ParmVarDecl {{.*}} <col:69, col:73> col:73 imported in mod hidden referenced v 'Rep' | ||
| // CHECK-NEXT: | | `-SimpleRequirement {{.*}} dependent | ||
| // CHECK-NEXT: | | `-CallExpr {{.*}} <col:77, col:82> '<dependent type>' | ||
| // CHECK-NEXT: | | |-UnresolvedLookupExpr {{.*}} <col:77> '<overloaded function type>' lvalue (ADL) = 'cos' empty | ||
| // CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:81> 'Rep' lvalue ParmVar {{.*}} 'v' 'Rep' non_odr_use_unevaluated | ||
| // CHECK-NEXT: | `-FunctionDecl {{.*}} <line:12:1, col:22> col:6 imported in mod hidden cos 'auto (const Rep &)' | ||
| // CHECK-NEXT: | `-ParmVarDecl {{.*}} <col:10, col:21> col:21 imported in mod hidden q 'const Rep &' | ||
|
|
||
| // CHECK: |-FunctionTemplateDecl {{.*}} <line:15:1, line:16:22> col:6 imported in mod hidden invalid tan | ||
| // CHECK-NEXT: | |-NonTypeTemplateParmDecl {{.*}} <line:15:10, col:34> col:34 imported in mod hidden referenced invalid 'ReferenceOf<angle> auto' depth 0 index 0 R | ||
| // CHECK-NEXT: | | `-RecoveryExpr {{.*}} <col:10, col:34> 'ReferenceOf<angle> auto' contains-errors lvalue | ||
| // CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} <col:37, col:46> col:46 imported in mod hidden referenced typename depth 0 index 1 Rep | ||
| // CHECK-NEXT: | |-RequiresExpr {{.*}} <col:60, col:84> 'bool' | ||
| // CHECK-NEXT: | | |-ParmVarDecl {{.*}} <col:69, col:73> col:73 imported in mod hidden referenced v 'Rep' | ||
| // CHECK-NEXT: | | `-SimpleRequirement {{.*}} dependent | ||
| // CHECK-NEXT: | | `-CallExpr {{.*}} <col:77, col:82> '<dependent type>' | ||
| // CHECK-NEXT: | | |-UnresolvedLookupExpr {{.*}} <col:77> '<overloaded function type>' lvalue (ADL) = 'tan' empty | ||
| // CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:81> 'Rep' lvalue ParmVar {{.*}} 'v' 'Rep' non_odr_use_unevaluated | ||
| // CHECK-NEXT: | `-FunctionDecl {{.*}} <line:16:1, col:22> col:6 imported in mod hidden tan 'auto (const Rep &)' | ||
| // CHECK-NEXT: | `-ParmVarDecl {{.*}} <col:10, col:21> col:21 imported in mod hidden q 'const Rep &' | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can that actually fail? I wonder if we should not just assert
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took the existing
if, but looking atBuildDeclRefExprit doesn't seem like it could returnnullptr.I have dropped the condition and added an assert instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1,
BuildDeclRefExprwouldn't fail with a nullptr