[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
sdkrystian wrote: @zyn0217 Yes, both examples are of uninstantiable templates & are intended to be diagnosed by #90152. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
zyn0217 wrote: > It seems this change cause https://godbolt.org/z/311nb6xYe to fail. Could you > please take look? > Also: > https://godbolt.org/z/bYs7Y9v11 I don't see any justification that these examples should compile: the first example is a typical one handled by #90152 (from the release note): ```rst - Clang now looks up members of the current instantiation in the template definition context if the current instantiation has no dependent base classes. template struct A { int f() { return this->x; // error: no member named 'x' in 'A' } }; ``` and the second one would also be rejected by GCC once the inner class `b` gets instantiated. This earlier diagnostic is probably also triggered by #90152, but I'm not sure. @sdkrystian, is this behavior intended and from your recent patches? https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
jyu2-git wrote: Hi @zyn0217, I am not sure. But if I revert your patch, two tests compiles. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
zyn0217 wrote: @jyu2-git Are you sure this is the patch you’re looking for? The diagnostic there is completely unrelated and I think the right patch is https://github.com/llvm/llvm-project/pull/90152. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
jyu2-git wrote: Hi @zyn0217. It seems this change cause https://godbolt.org/z/311nb6xYe to fail. Could you please take look? Thanks. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
zyn0217 wrote: @aganea Oops, this is an oversight I think, because I don't build lldb locally nor run its tests... I'm proposing a PR https://github.com/llvm/llvm-project/pull/91132, can you help me confirm if that works? https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
aganea wrote: Hello, This causes a warning when building LLDB on Windows, `clang::BuiltinType::UnresolvedTemplate` isn't handled in the case in the file indicated below (sorry my locale is French). Would you have a chance to take a look @zyn0217 please? ``` [6325/7521] Building CXX object tools\lldb\source\Plugins\TypeSystem\Clang\CMakeFiles\lldbPluginTypeSystemClang.dir\TypeSystemClang.cpp.obj C:\src\git\llvm-project\lldb\source\Plugins\TypeSystem\Clang\TypeSystemClang.cpp(4999): warning C4062: L'énumérateur 'clang::BuiltinType::UnresolvedTemplate' dans le commutateur de l'énumération 'clang::BuiltinType::Kind' n'est pas géré. C:\src\git\llvm-project\clang\include\clang/AST/Type.h(2983): note: voir la déclaration de 'clang::BuiltinType::Kind' ``` https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 closed https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/89019 >From 89a5bbcc89c1e43ac7f2e60f3c234c2c42928c86 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Wed, 17 Apr 2024 12:24:56 +0800 Subject: [PATCH 1/7] [clang] Distinguish unresolved templates in UnresolvedLookupExpr This patch revolves around the misuse of UnresolvedLookupExpr in BuildTemplateIdExpr. Basically, we build up an UnresolvedLookupExpr not only for function overloads but for "unresolved" templates wherever we need an expression for template decls. For example, a dependent VarTemplateDecl can be wrapped with such an expression before template instantiation. (See https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9) Also, one important thing is that UnresolvedLookupExpr uses a "canonical" QualType to describe the containing unresolved decls: a DependentTy is for dependent expressions and an OverloadTy otherwise. Therefore, this modeling for non-dependent templates leaves a problem in that the expression is marked and perceived as if describing overload functions. The consumer then expects functions for every such expression, although the fact is the reverse. Hence, we run into crashes. As to the patch, I added a new canonical type "UnresolvedTemplateTy" to model these cases. Given that we have been using this model (intentionally or accidentally) and it is pretty baked in throughout the code, I think extending the role of UnresolvedLookupExpr is reasonable. Further, I added some diagnostics for the direct occurrence of these expressions, which are supposed to be ill-formed. As a bonus, this patch also fixes some typos in the diagnostics and creates RecoveryExprs rather than nothing in the hope of a better error-recovery for clangd. Fixes https://github.com/llvm/llvm-project/issues/88832 Fixes https://github.com/llvm/llvm-project/issues/63243 Fixes https://github.com/llvm/llvm-project/issues/48673 --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/AST/ASTContext.h | 3 +- clang/include/clang/AST/BuiltinTypes.def | 3 + .../include/clang/Serialization/ASTBitCodes.h | 5 +- clang/lib/AST/ASTContext.cpp | 3 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp| 3 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 19 + clang/lib/Sema/SemaTemplate.cpp | 13 +++- clang/lib/Serialization/ASTCommon.cpp | 3 + clang/lib/Serialization/ASTReader.cpp | 3 + clang/test/SemaCXX/PR62533.cpp| 2 +- clang/test/SemaTemplate/template-id-expr.cpp | 71 +++ 14 files changed, 125 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efc32212f300cf..8c50988083faa6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -535,6 +535,7 @@ Bug Fixes to C++ Support - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Placement new initializes typedef array with correct size (#GH41441) +- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) and (#GH88832). Bug Fixes to AST Handling ^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..fd0cc10be8ebca 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/89019 >From 89a5bbcc89c1e43ac7f2e60f3c234c2c42928c86 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Wed, 17 Apr 2024 12:24:56 +0800 Subject: [PATCH 1/7] [clang] Distinguish unresolved templates in UnresolvedLookupExpr This patch revolves around the misuse of UnresolvedLookupExpr in BuildTemplateIdExpr. Basically, we build up an UnresolvedLookupExpr not only for function overloads but for "unresolved" templates wherever we need an expression for template decls. For example, a dependent VarTemplateDecl can be wrapped with such an expression before template instantiation. (See https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9) Also, one important thing is that UnresolvedLookupExpr uses a "canonical" QualType to describe the containing unresolved decls: a DependentTy is for dependent expressions and an OverloadTy otherwise. Therefore, this modeling for non-dependent templates leaves a problem in that the expression is marked and perceived as if describing overload functions. The consumer then expects functions for every such expression, although the fact is the reverse. Hence, we run into crashes. As to the patch, I added a new canonical type "UnresolvedTemplateTy" to model these cases. Given that we have been using this model (intentionally or accidentally) and it is pretty baked in throughout the code, I think extending the role of UnresolvedLookupExpr is reasonable. Further, I added some diagnostics for the direct occurrence of these expressions, which are supposed to be ill-formed. As a bonus, this patch also fixes some typos in the diagnostics and creates RecoveryExprs rather than nothing in the hope of a better error-recovery for clangd. Fixes https://github.com/llvm/llvm-project/issues/88832 Fixes https://github.com/llvm/llvm-project/issues/63243 Fixes https://github.com/llvm/llvm-project/issues/48673 --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/AST/ASTContext.h | 3 +- clang/include/clang/AST/BuiltinTypes.def | 3 + .../include/clang/Serialization/ASTBitCodes.h | 5 +- clang/lib/AST/ASTContext.cpp | 3 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp| 3 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 19 + clang/lib/Sema/SemaTemplate.cpp | 13 +++- clang/lib/Serialization/ASTCommon.cpp | 3 + clang/lib/Serialization/ASTReader.cpp | 3 + clang/test/SemaCXX/PR62533.cpp| 2 +- clang/test/SemaTemplate/template-id-expr.cpp | 71 +++ 14 files changed, 125 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efc32212f300cf..8c50988083faa6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -535,6 +535,7 @@ Bug Fixes to C++ Support - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Placement new initializes typedef array with correct size (#GH41441) +- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) and (#GH88832). Bug Fixes to AST Handling ^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..fd0cc10be8ebca 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/michaelmaitland updated https://github.com/llvm/llvm-project/pull/89019 >From 89a5bbcc89c1e43ac7f2e60f3c234c2c42928c86 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Wed, 17 Apr 2024 12:24:56 +0800 Subject: [PATCH 1/7] [clang] Distinguish unresolved templates in UnresolvedLookupExpr This patch revolves around the misuse of UnresolvedLookupExpr in BuildTemplateIdExpr. Basically, we build up an UnresolvedLookupExpr not only for function overloads but for "unresolved" templates wherever we need an expression for template decls. For example, a dependent VarTemplateDecl can be wrapped with such an expression before template instantiation. (See https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9) Also, one important thing is that UnresolvedLookupExpr uses a "canonical" QualType to describe the containing unresolved decls: a DependentTy is for dependent expressions and an OverloadTy otherwise. Therefore, this modeling for non-dependent templates leaves a problem in that the expression is marked and perceived as if describing overload functions. The consumer then expects functions for every such expression, although the fact is the reverse. Hence, we run into crashes. As to the patch, I added a new canonical type "UnresolvedTemplateTy" to model these cases. Given that we have been using this model (intentionally or accidentally) and it is pretty baked in throughout the code, I think extending the role of UnresolvedLookupExpr is reasonable. Further, I added some diagnostics for the direct occurrence of these expressions, which are supposed to be ill-formed. As a bonus, this patch also fixes some typos in the diagnostics and creates RecoveryExprs rather than nothing in the hope of a better error-recovery for clangd. Fixes https://github.com/llvm/llvm-project/issues/88832 Fixes https://github.com/llvm/llvm-project/issues/63243 Fixes https://github.com/llvm/llvm-project/issues/48673 --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/AST/ASTContext.h | 3 +- clang/include/clang/AST/BuiltinTypes.def | 3 + .../include/clang/Serialization/ASTBitCodes.h | 5 +- clang/lib/AST/ASTContext.cpp | 3 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp| 3 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 19 + clang/lib/Sema/SemaTemplate.cpp | 13 +++- clang/lib/Serialization/ASTCommon.cpp | 3 + clang/lib/Serialization/ASTReader.cpp | 3 + clang/test/SemaCXX/PR62533.cpp| 2 +- clang/test/SemaTemplate/template-id-expr.cpp | 71 +++ 14 files changed, 125 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efc32212f300cf..8c50988083faa6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -535,6 +535,7 @@ Bug Fixes to C++ Support - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Placement new initializes typedef array with correct size (#GH41441) +- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) and (#GH88832). Bug Fixes to AST Handling ^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..fd0cc10be8ebca 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/erichkeane approved this pull request. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
zyn0217 wrote: > This is introducing a new type that has a pretty subtle difference vs others. > Can we have some documentation in the internals manual explaining the > difference? > > Code wise, I think this looks fine. Yeah, I added some explanation to the document of `UnresolvedLookupExpr`; further, I didn't see anything specific to the topic of `UnresolvedLookupExpr` in the `InternalsManual.rst`, so I hope this is sufficient? https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/89019 >From 89a5bbcc89c1e43ac7f2e60f3c234c2c42928c86 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Wed, 17 Apr 2024 12:24:56 +0800 Subject: [PATCH 1/6] [clang] Distinguish unresolved templates in UnresolvedLookupExpr This patch revolves around the misuse of UnresolvedLookupExpr in BuildTemplateIdExpr. Basically, we build up an UnresolvedLookupExpr not only for function overloads but for "unresolved" templates wherever we need an expression for template decls. For example, a dependent VarTemplateDecl can be wrapped with such an expression before template instantiation. (See https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9) Also, one important thing is that UnresolvedLookupExpr uses a "canonical" QualType to describe the containing unresolved decls: a DependentTy is for dependent expressions and an OverloadTy otherwise. Therefore, this modeling for non-dependent templates leaves a problem in that the expression is marked and perceived as if describing overload functions. The consumer then expects functions for every such expression, although the fact is the reverse. Hence, we run into crashes. As to the patch, I added a new canonical type "UnresolvedTemplateTy" to model these cases. Given that we have been using this model (intentionally or accidentally) and it is pretty baked in throughout the code, I think extending the role of UnresolvedLookupExpr is reasonable. Further, I added some diagnostics for the direct occurrence of these expressions, which are supposed to be ill-formed. As a bonus, this patch also fixes some typos in the diagnostics and creates RecoveryExprs rather than nothing in the hope of a better error-recovery for clangd. Fixes https://github.com/llvm/llvm-project/issues/88832 Fixes https://github.com/llvm/llvm-project/issues/63243 Fixes https://github.com/llvm/llvm-project/issues/48673 --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/AST/ASTContext.h | 3 +- clang/include/clang/AST/BuiltinTypes.def | 3 + .../include/clang/Serialization/ASTBitCodes.h | 5 +- clang/lib/AST/ASTContext.cpp | 3 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp| 3 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 19 + clang/lib/Sema/SemaTemplate.cpp | 13 +++- clang/lib/Serialization/ASTCommon.cpp | 3 + clang/lib/Serialization/ASTReader.cpp | 3 + clang/test/SemaCXX/PR62533.cpp| 2 +- clang/test/SemaTemplate/template-id-expr.cpp | 71 +++ 14 files changed, 125 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efc32212f300cf..8c50988083faa6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -535,6 +535,7 @@ Bug Fixes to C++ Support - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Placement new initializes typedef array with correct size (#GH41441) +- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) and (#GH88832). Bug Fixes to AST Handling ^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..fd0cc10be8ebca 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/erichkeane commented: This is introducing a new type that has a pretty subtle difference vs others. Can we have some documentation in the internals manual explaining the difference? Code wise, I think this looks fine. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
zyn0217 wrote: @cor3ntin @erichkeane Any chance we can move forward with this review? I appreciate your feedback! https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} + } +}; + +int bar() { + return Q().foo(); // expected-note-re {{function template specialization {{.*}} requested here}} +} + +} // namespace PR88832 +#endif + +namespace PR63243 { + +namespace std { +template struct add_pointer { // #add_pointer +}; +} // namespace std + +class A {}; + +int main() { + std::__add_pointer::type ptr; // #ill-formed-decl + // expected-error@#ill-formed-decl {{no template named '__add_pointer'}} + // expected-note@#add_pointer {{'add_pointer' declared here}} + // expected-error@#ill-formed-decl {{expected ';' after expression}} + // expected-error@#ill-formed-decl {{no type named 'type' in the global namespace}} + // expected-error@#ill-formed-decl {{'std::add_pointer' is expected to be a non-type template, but instantiated to a class template}} zyn0217 wrote: @cor3ntin do you have any thoughts here? thanks! https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/89019 >From 89a5bbcc89c1e43ac7f2e60f3c234c2c42928c86 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Wed, 17 Apr 2024 12:24:56 +0800 Subject: [PATCH 1/5] [clang] Distinguish unresolved templates in UnresolvedLookupExpr This patch revolves around the misuse of UnresolvedLookupExpr in BuildTemplateIdExpr. Basically, we build up an UnresolvedLookupExpr not only for function overloads but for "unresolved" templates wherever we need an expression for template decls. For example, a dependent VarTemplateDecl can be wrapped with such an expression before template instantiation. (See https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9) Also, one important thing is that UnresolvedLookupExpr uses a "canonical" QualType to describe the containing unresolved decls: a DependentTy is for dependent expressions and an OverloadTy otherwise. Therefore, this modeling for non-dependent templates leaves a problem in that the expression is marked and perceived as if describing overload functions. The consumer then expects functions for every such expression, although the fact is the reverse. Hence, we run into crashes. As to the patch, I added a new canonical type "UnresolvedTemplateTy" to model these cases. Given that we have been using this model (intentionally or accidentally) and it is pretty baked in throughout the code, I think extending the role of UnresolvedLookupExpr is reasonable. Further, I added some diagnostics for the direct occurrence of these expressions, which are supposed to be ill-formed. As a bonus, this patch also fixes some typos in the diagnostics and creates RecoveryExprs rather than nothing in the hope of a better error-recovery for clangd. Fixes https://github.com/llvm/llvm-project/issues/88832 Fixes https://github.com/llvm/llvm-project/issues/63243 Fixes https://github.com/llvm/llvm-project/issues/48673 --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/AST/ASTContext.h | 3 +- clang/include/clang/AST/BuiltinTypes.def | 3 + .../include/clang/Serialization/ASTBitCodes.h | 5 +- clang/lib/AST/ASTContext.cpp | 3 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp| 3 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 19 + clang/lib/Sema/SemaTemplate.cpp | 13 +++- clang/lib/Serialization/ASTCommon.cpp | 3 + clang/lib/Serialization/ASTReader.cpp | 3 + clang/test/SemaCXX/PR62533.cpp| 2 +- clang/test/SemaTemplate/template-id-expr.cpp | 71 +++ 14 files changed, 125 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efc32212f300cf..8c50988083faa6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -535,6 +535,7 @@ Bug Fixes to C++ Support - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Placement new initializes typedef array with correct size (#GH41441) +- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) and (#GH88832). Bug Fixes to AST Handling ^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..fd0cc10be8ebca 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} + } +}; + +int bar() { + return Q().foo(); // expected-note-re {{function template specialization {{.*}} requested here}} +} + +} // namespace PR88832 +#endif + +namespace PR63243 { + +namespace std { +template struct add_pointer { // #add_pointer +}; +} // namespace std + +class A {}; + +int main() { + std::__add_pointer::type ptr; // #ill-formed-decl + // expected-error@#ill-formed-decl {{no template named '__add_pointer'}} + // expected-note@#add_pointer {{'add_pointer' declared here}} + // expected-error@#ill-formed-decl {{expected ';' after expression}} + // expected-error@#ill-formed-decl {{no type named 'type' in the global namespace}} + // expected-error@#ill-formed-decl {{'std::add_pointer' is expected to be a non-type template, but instantiated to a class template}} erichkeane wrote: I think that would be OK? But @cor3ntin would be our expert there. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/89019 >From 89a5bbcc89c1e43ac7f2e60f3c234c2c42928c86 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Wed, 17 Apr 2024 12:24:56 +0800 Subject: [PATCH 1/4] [clang] Distinguish unresolved templates in UnresolvedLookupExpr This patch revolves around the misuse of UnresolvedLookupExpr in BuildTemplateIdExpr. Basically, we build up an UnresolvedLookupExpr not only for function overloads but for "unresolved" templates wherever we need an expression for template decls. For example, a dependent VarTemplateDecl can be wrapped with such an expression before template instantiation. (See https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9) Also, one important thing is that UnresolvedLookupExpr uses a "canonical" QualType to describe the containing unresolved decls: a DependentTy is for dependent expressions and an OverloadTy otherwise. Therefore, this modeling for non-dependent templates leaves a problem in that the expression is marked and perceived as if describing overload functions. The consumer then expects functions for every such expression, although the fact is the reverse. Hence, we run into crashes. As to the patch, I added a new canonical type "UnresolvedTemplateTy" to model these cases. Given that we have been using this model (intentionally or accidentally) and it is pretty baked in throughout the code, I think extending the role of UnresolvedLookupExpr is reasonable. Further, I added some diagnostics for the direct occurrence of these expressions, which are supposed to be ill-formed. As a bonus, this patch also fixes some typos in the diagnostics and creates RecoveryExprs rather than nothing in the hope of a better error-recovery for clangd. Fixes https://github.com/llvm/llvm-project/issues/88832 Fixes https://github.com/llvm/llvm-project/issues/63243 Fixes https://github.com/llvm/llvm-project/issues/48673 --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/AST/ASTContext.h | 3 +- clang/include/clang/AST/BuiltinTypes.def | 3 + .../include/clang/Serialization/ASTBitCodes.h | 5 +- clang/lib/AST/ASTContext.cpp | 3 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp| 3 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 19 + clang/lib/Sema/SemaTemplate.cpp | 13 +++- clang/lib/Serialization/ASTCommon.cpp | 3 + clang/lib/Serialization/ASTReader.cpp | 3 + clang/test/SemaCXX/PR62533.cpp| 2 +- clang/test/SemaTemplate/template-id-expr.cpp | 71 +++ 14 files changed, 125 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efc32212f300cf..8c50988083faa6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -535,6 +535,7 @@ Bug Fixes to C++ Support - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Placement new initializes typedef array with correct size (#GH41441) +- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) and (#GH88832). Bug Fixes to AST Handling ^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..fd0cc10be8ebca 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} + } +}; + +int bar() { + return Q().foo(); // expected-note-re {{function template specialization {{.*}} requested here}} +} + +} // namespace PR88832 +#endif + +namespace PR63243 { + +namespace std { +template struct add_pointer { // #add_pointer +}; +} // namespace std + +class A {}; + +int main() { + std::__add_pointer::type ptr; // #ill-formed-decl + // expected-error@#ill-formed-decl {{no template named '__add_pointer'}} + // expected-note@#add_pointer {{'add_pointer' declared here}} + // expected-error@#ill-formed-decl {{expected ';' after expression}} + // expected-error@#ill-formed-decl {{no type named 'type' in the global namespace}} + // expected-error@#ill-formed-decl {{'std::add_pointer' is expected to be a non-type template, but instantiated to a class template}} zyn0217 wrote: > As far as this diagnostic, can you spend a little time to evaluate how much > work it is to fix that? It is particularly awkward. I have looked into it a bit more, and I found it is a consequence of not handling `TRANSFORM_TYPE_TRAIT`s as scope specifiers, which was introduced in e9ef45635. Let's explain the difference with an example: ```cpp namespace std { struct add_pointer {}; } void foo() { std::__add_pointer::type ptr; std::Add_pointer::type ptr2; } ``` we would end up seeing different diagnostics on two declarations `ptr` and `ptr2`: the first is what was crashing previously, because `__add_pointer` is actually a keyword rather than an identifier like `Add_pointer`. As a result, we would bail out when we see `__add_pointer` in `ParseOptionalCXXScopeSpecifier`, and we would continue parsing it as a `TemplateIdExpr`, which gave us a crash as well as a spurious diagnostic saying we're missing a semicolon after ``. For comparison, the second case would keep parsing until we encounter the semicolon after `ptr2`. This results in a better diagnostic even after the typo correction. I think a fix would be to add a handling logic to `ParseOptionalCXXScopeSpecifier` like what we did in e9ef45635: ```cpp switch (Tok.getKind()) { #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: #include "clang/Basic/TransformTypeTraits.def" if (NextToken().is(tok::less)) { Tok.setKind(tok::identifier); Diag(Tok, diag::ext_keyword_as_ident) << Tok.getIdentifierInfo()->getName() << 0; continue; } LLVM_FALLTHROUGH; default: break; } ``` https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} erichkeane wrote: FWIW, I think I'm the 'first' person who has really been pushing for using the bookmarks for notes, no one ever has before, but when reviewing template stuff in particular, it is REALLY bad, so as code-owner, its one of the things I push for in new commits :) So you'll see very few that do it, but hopefully more happening. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} Sirraide wrote: That’s true; I’ve run into cases before where the notes just ended up being a mess... https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} erichkeane wrote: Yeah, it doesn't make sense for errors/warnings: Those should be "right next" to the thing that caused them (so I prefer the +/- Numeral for those). However, with Notes, it makes a TON of sense, and IMO, should nearly ALWAYS be used. Without them, we end up getting 'errors' and their notes are completely unintelligible, because they are spread out around the file and in no reasonable order. It makes it so figuring out "this is an error only because of these instantiations" is impossible. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} Sirraide wrote: > It makes it easier to determine which error is causing the note. Iirc last time this came up in a discussion the consensus was that it was better not to use markers, but I think that was more about actual errors than notes, because this makes sense, yeah. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} + } +}; + +int bar() { + return Q().foo(); // expected-note-re {{function template specialization {{.*}} requested here}} +} + +} // namespace PR88832 +#endif + +namespace PR63243 { + +namespace std { +template struct add_pointer { // #add_pointer +}; +} // namespace std + +class A {}; + +int main() { + std::__add_pointer::type ptr; // #ill-formed-decl + // expected-error@#ill-formed-decl {{no template named '__add_pointer'}} + // expected-note@#add_pointer {{'add_pointer' declared here}} + // expected-error@#ill-formed-decl {{expected ';' after expression}} + // expected-error@#ill-formed-decl {{no type named 'type' in the global namespace}} + // expected-error@#ill-formed-decl {{'std::add_pointer' is expected to be a non-type template, but instantiated to a class template}} erichkeane wrote: This is a case where just doing the `-N` positioning is fine, since it is on the same thing here. As far as this diagnostic, can you spend a little time to evaluate how much work it is to fix that? It is particularly awkward. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} erichkeane wrote: I VASTLY prefer the markers. It makes it easier to determine which error is causing the note. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} zyn0217 wrote: > Can you add some more tests that involve an expression with this new type as > the argument to a function call? Done. Thanks for the feedback. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} zyn0217 wrote: I think this is more of a preference - subjectively, I feel like using markers makes the diagnostics concentrated, and one can see them in a somewhat consistent block without guessing what else notes/warnings an error diagnostic would also provide, though this looks a bit untidy. :( https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/89019 >From 89a5bbcc89c1e43ac7f2e60f3c234c2c42928c86 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Wed, 17 Apr 2024 12:24:56 +0800 Subject: [PATCH 1/3] [clang] Distinguish unresolved templates in UnresolvedLookupExpr This patch revolves around the misuse of UnresolvedLookupExpr in BuildTemplateIdExpr. Basically, we build up an UnresolvedLookupExpr not only for function overloads but for "unresolved" templates wherever we need an expression for template decls. For example, a dependent VarTemplateDecl can be wrapped with such an expression before template instantiation. (See https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9) Also, one important thing is that UnresolvedLookupExpr uses a "canonical" QualType to describe the containing unresolved decls: a DependentTy is for dependent expressions and an OverloadTy otherwise. Therefore, this modeling for non-dependent templates leaves a problem in that the expression is marked and perceived as if describing overload functions. The consumer then expects functions for every such expression, although the fact is the reverse. Hence, we run into crashes. As to the patch, I added a new canonical type "UnresolvedTemplateTy" to model these cases. Given that we have been using this model (intentionally or accidentally) and it is pretty baked in throughout the code, I think extending the role of UnresolvedLookupExpr is reasonable. Further, I added some diagnostics for the direct occurrence of these expressions, which are supposed to be ill-formed. As a bonus, this patch also fixes some typos in the diagnostics and creates RecoveryExprs rather than nothing in the hope of a better error-recovery for clangd. Fixes https://github.com/llvm/llvm-project/issues/88832 Fixes https://github.com/llvm/llvm-project/issues/63243 Fixes https://github.com/llvm/llvm-project/issues/48673 --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/AST/ASTContext.h | 3 +- clang/include/clang/AST/BuiltinTypes.def | 3 + .../include/clang/Serialization/ASTBitCodes.h | 5 +- clang/lib/AST/ASTContext.cpp | 3 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp| 3 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 19 + clang/lib/Sema/SemaTemplate.cpp | 13 +++- clang/lib/Serialization/ASTCommon.cpp | 3 + clang/lib/Serialization/ASTReader.cpp | 3 + clang/test/SemaCXX/PR62533.cpp| 2 +- clang/test/SemaTemplate/template-id-expr.cpp | 71 +++ 14 files changed, 125 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efc32212f300cf..8c50988083faa6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -535,6 +535,7 @@ Bug Fixes to C++ Support - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Placement new initializes typedef array with correct size (#GH41441) +- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) and (#GH88832). Bug Fixes to AST Handling ^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..fd0cc10be8ebca 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/89019 >From 89a5bbcc89c1e43ac7f2e60f3c234c2c42928c86 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Wed, 17 Apr 2024 12:24:56 +0800 Subject: [PATCH 1/2] [clang] Distinguish unresolved templates in UnresolvedLookupExpr This patch revolves around the misuse of UnresolvedLookupExpr in BuildTemplateIdExpr. Basically, we build up an UnresolvedLookupExpr not only for function overloads but for "unresolved" templates wherever we need an expression for template decls. For example, a dependent VarTemplateDecl can be wrapped with such an expression before template instantiation. (See https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9) Also, one important thing is that UnresolvedLookupExpr uses a "canonical" QualType to describe the containing unresolved decls: a DependentTy is for dependent expressions and an OverloadTy otherwise. Therefore, this modeling for non-dependent templates leaves a problem in that the expression is marked and perceived as if describing overload functions. The consumer then expects functions for every such expression, although the fact is the reverse. Hence, we run into crashes. As to the patch, I added a new canonical type "UnresolvedTemplateTy" to model these cases. Given that we have been using this model (intentionally or accidentally) and it is pretty baked in throughout the code, I think extending the role of UnresolvedLookupExpr is reasonable. Further, I added some diagnostics for the direct occurrence of these expressions, which are supposed to be ill-formed. As a bonus, this patch also fixes some typos in the diagnostics and creates RecoveryExprs rather than nothing in the hope of a better error-recovery for clangd. Fixes https://github.com/llvm/llvm-project/issues/88832 Fixes https://github.com/llvm/llvm-project/issues/63243 Fixes https://github.com/llvm/llvm-project/issues/48673 --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/AST/ASTContext.h | 3 +- clang/include/clang/AST/BuiltinTypes.def | 3 + .../include/clang/Serialization/ASTBitCodes.h | 5 +- clang/lib/AST/ASTContext.cpp | 3 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp| 3 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 19 + clang/lib/Sema/SemaTemplate.cpp | 13 +++- clang/lib/Serialization/ASTCommon.cpp | 3 + clang/lib/Serialization/ASTReader.cpp | 3 + clang/test/SemaCXX/PR62533.cpp| 2 +- clang/test/SemaTemplate/template-id-expr.cpp | 71 +++ 14 files changed, 125 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efc32212f300cf..8c50988083faa6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -535,6 +535,7 @@ Bug Fixes to C++ Support - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Placement new initializes typedef array with correct size (#GH41441) +- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) and (#GH88832). Bug Fixes to AST Handling ^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..fd0cc10be8ebca 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/Sirraide edited https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} Sirraide wrote: The same applies to the other diagnostics using markers below. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} Sirraide wrote: I’d suggest putting this on the line where the note is emitted rather than using markers whenever possible. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/Sirraide commented: I think the general approach of this makes sense. Can you add some more tests that involve an expression with this new type as the argument to a function call? You’ve taken care of handling that case from what I’ve seen, but having tests for that would probably be a good idea. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Younan Zhang (zyn0217) Changes This patch revolves around the misuse of UnresolvedLookupExpr in BuildTemplateIdExpr. Basically, we build up an UnresolvedLookupExpr not only for function overloads but for "unresolved" templates wherever we need an expression for template decls. For example, a dependent VarTemplateDecl can be wrapped with such an expression before template instantiation. (See https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9) Also, one important thing is that UnresolvedLookupExpr uses a "canonical" QualType to describe the containing unresolved decls: a DependentTy is for dependent expressions and an OverloadTy otherwise. Therefore, this modeling for non-dependent templates leaves a problem in that the expression is marked and perceived as if describing overload functions. The consumer then expects functions for every such expression, although the fact is the reverse. Hence, we run into crashes. As to the patch, I added a new canonical type "UnresolvedTemplateTy" to model these cases. Given that we have been using this model (intentionally or accidentally) and it is pretty baked in throughout the code, I think extending the role of UnresolvedLookupExpr is reasonable. Further, I added some diagnostics for the direct occurrence of these expressions, which are supposed to be ill-formed. As a bonus, this patch also fixes some typos in the diagnostics and creates RecoveryExprs rather than nothing in the hope of a better error-recovery for clangd. Fixes https://github.com/llvm/llvm-project/issues/88832 Fixes https://github.com/llvm/llvm-project/issues/63243 Fixes https://github.com/llvm/llvm-project/issues/48673 --- Full diff: https://github.com/llvm/llvm-project/pull/89019.diff 14 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/include/clang/AST/ASTContext.h (+2-1) - (modified) clang/include/clang/AST/BuiltinTypes.def (+3) - (modified) clang/include/clang/Serialization/ASTBitCodes.h (+4-1) - (modified) clang/lib/AST/ASTContext.cpp (+3) - (modified) clang/lib/AST/NSAPI.cpp (+1) - (modified) clang/lib/AST/Type.cpp (+3) - (modified) clang/lib/AST/TypeLoc.cpp (+1) - (modified) clang/lib/Sema/SemaExpr.cpp (+19) - (modified) clang/lib/Sema/SemaTemplate.cpp (+10-3) - (modified) clang/lib/Serialization/ASTCommon.cpp (+3) - (modified) clang/lib/Serialization/ASTReader.cpp (+3) - (modified) clang/test/SemaCXX/PR62533.cpp (+1-1) - (modified) clang/test/SemaTemplate/template-id-expr.cpp (+71) ``diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efc32212f300cf..8c50988083faa6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -535,6 +535,7 @@ Bug Fixes to C++ Support - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Placement new initializes typedef array with correct size (#GH41441) +- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) and (#GH88832). Bug Fixes to AST Handling ^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..fd0cc10be8ebca 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 500098dd3dab1d..2f0a122fdfde14 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
llvmbot wrote: @llvm/pr-subscribers-clang-modules Author: Younan Zhang (zyn0217) Changes This patch revolves around the misuse of UnresolvedLookupExpr in BuildTemplateIdExpr. Basically, we build up an UnresolvedLookupExpr not only for function overloads but for "unresolved" templates wherever we need an expression for template decls. For example, a dependent VarTemplateDecl can be wrapped with such an expression before template instantiation. (See https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9) Also, one important thing is that UnresolvedLookupExpr uses a "canonical" QualType to describe the containing unresolved decls: a DependentTy is for dependent expressions and an OverloadTy otherwise. Therefore, this modeling for non-dependent templates leaves a problem in that the expression is marked and perceived as if describing overload functions. The consumer then expects functions for every such expression, although the fact is the reverse. Hence, we run into crashes. As to the patch, I added a new canonical type "UnresolvedTemplateTy" to model these cases. Given that we have been using this model (intentionally or accidentally) and it is pretty baked in throughout the code, I think extending the role of UnresolvedLookupExpr is reasonable. Further, I added some diagnostics for the direct occurrence of these expressions, which are supposed to be ill-formed. As a bonus, this patch also fixes some typos in the diagnostics and creates RecoveryExprs rather than nothing in the hope of a better error-recovery for clangd. Fixes https://github.com/llvm/llvm-project/issues/88832 Fixes https://github.com/llvm/llvm-project/issues/63243 Fixes https://github.com/llvm/llvm-project/issues/48673 --- Full diff: https://github.com/llvm/llvm-project/pull/89019.diff 14 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/include/clang/AST/ASTContext.h (+2-1) - (modified) clang/include/clang/AST/BuiltinTypes.def (+3) - (modified) clang/include/clang/Serialization/ASTBitCodes.h (+4-1) - (modified) clang/lib/AST/ASTContext.cpp (+3) - (modified) clang/lib/AST/NSAPI.cpp (+1) - (modified) clang/lib/AST/Type.cpp (+3) - (modified) clang/lib/AST/TypeLoc.cpp (+1) - (modified) clang/lib/Sema/SemaExpr.cpp (+19) - (modified) clang/lib/Sema/SemaTemplate.cpp (+10-3) - (modified) clang/lib/Serialization/ASTCommon.cpp (+3) - (modified) clang/lib/Serialization/ASTReader.cpp (+3) - (modified) clang/test/SemaCXX/PR62533.cpp (+1-1) - (modified) clang/test/SemaTemplate/template-id-expr.cpp (+71) ``diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efc32212f300cf..8c50988083faa6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -535,6 +535,7 @@ Bug Fixes to C++ Support - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Placement new initializes typedef array with correct size (#GH41441) +- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) and (#GH88832). Bug Fixes to AST Handling ^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..fd0cc10be8ebca 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 500098dd3dab1d..2f0a122fdfde14 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 ready_for_review https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
zyn0217 wrote: The pre-commit CI is still clogging after a few hours, and I'm opening it for feedback anyway. https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
@@ -186,3 +186,74 @@ class E { #endif template using D = int; // expected-note {{declared here}} E ed; // expected-note {{instantiation of}} + +namespace non_functions { + +#if __cplusplus >= 201103L +namespace PR88832 { +template struct O { + static const T v = 0; +}; + +struct P { + template using I = typename O::v; // #TypeAlias +}; + +struct Q { + template int foo() { +return T::template I; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}} +// expected-note@#TypeAlias {{type alias template declared here}} + } +}; + +int bar() { + return Q().foo(); // expected-note-re {{function template specialization {{.*}} requested here}} +} + +} // namespace PR88832 +#endif + +namespace PR63243 { + +namespace std { +template struct add_pointer { // #add_pointer +}; +} // namespace std + +class A {}; + +int main() { + std::__add_pointer::type ptr; // #ill-formed-decl + // expected-error@#ill-formed-decl {{no template named '__add_pointer'}} + // expected-note@#add_pointer {{'add_pointer' declared here}} + // expected-error@#ill-formed-decl {{expected ';' after expression}} + // expected-error@#ill-formed-decl {{no type named 'type' in the global namespace}} + // expected-error@#ill-formed-decl {{'std::add_pointer' is expected to be a non-type template, but instantiated to a class template}} zyn0217 wrote: RFC: this diagnostic is probably not optimal (and maybe confusing), since `CheckPlaceholderExpr` is called almost everywhere apart from a full expression. I was considering moving the diagnostic out of that function, but that requires much work I think. (and I'm a bit lazy :) https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 edited https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/89019 >From 89a5bbcc89c1e43ac7f2e60f3c234c2c42928c86 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Wed, 17 Apr 2024 12:24:56 +0800 Subject: [PATCH] [clang] Distinguish unresolved templates in UnresolvedLookupExpr This patch revolves around the misuse of UnresolvedLookupExpr in BuildTemplateIdExpr. Basically, we build up an UnresolvedLookupExpr not only for function overloads but for "unresolved" templates wherever we need an expression for template decls. For example, a dependent VarTemplateDecl can be wrapped with such an expression before template instantiation. (See https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9) Also, one important thing is that UnresolvedLookupExpr uses a "canonical" QualType to describe the containing unresolved decls: a DependentTy is for dependent expressions and an OverloadTy otherwise. Therefore, this modeling for non-dependent templates leaves a problem in that the expression is marked and perceived as if describing overload functions. The consumer then expects functions for every such expression, although the fact is the reverse. Hence, we run into crashes. As to the patch, I added a new canonical type "UnresolvedTemplateTy" to model these cases. Given that we have been using this model (intentionally or accidentally) and it is pretty baked in throughout the code, I think extending the role of UnresolvedLookupExpr is reasonable. Further, I added some diagnostics for the direct occurrence of these expressions, which are supposed to be ill-formed. As a bonus, this patch also fixes some typos in the diagnostics and creates RecoveryExprs rather than nothing in the hope of a better error-recovery for clangd. Fixes https://github.com/llvm/llvm-project/issues/88832 Fixes https://github.com/llvm/llvm-project/issues/63243 Fixes https://github.com/llvm/llvm-project/issues/48673 --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/AST/ASTContext.h | 3 +- clang/include/clang/AST/BuiltinTypes.def | 3 + .../include/clang/Serialization/ASTBitCodes.h | 5 +- clang/lib/AST/ASTContext.cpp | 3 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp| 3 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 19 + clang/lib/Sema/SemaTemplate.cpp | 13 +++- clang/lib/Serialization/ASTCommon.cpp | 3 + clang/lib/Serialization/ASTReader.cpp | 3 + clang/test/SemaCXX/PR62533.cpp| 2 +- clang/test/SemaTemplate/template-id-expr.cpp | 71 +++ 14 files changed, 125 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efc32212f300cf..8c50988083faa6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -535,6 +535,7 @@ Bug Fixes to C++ Support - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329). - Fix a crash in requires expression with templated base class member function. Fixes (#GH84020). - Placement new initializes typedef array with correct size (#GH41441) +- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243) and (#GH88832). Bug Fixes to AST Handling ^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..fd0cc10be8ebca 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 edited https://github.com/llvm/llvm-project/pull/89019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)
https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/89019 None >From e510a76d231de0e22ba52584a80f18deb6af91c6 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Wed, 17 Apr 2024 12:24:56 +0800 Subject: [PATCH] [clang] Distinguish unresolved templates in UnresolvedLookupExpr --- clang/include/clang/AST/ASTContext.h | 3 +- clang/include/clang/AST/BuiltinTypes.def | 2 + .../include/clang/Serialization/ASTBitCodes.h | 4 +- clang/lib/AST/ASTContext.cpp | 3 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp| 3 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 19 + clang/lib/Sema/SemaTemplate.cpp | 11 ++- clang/lib/Serialization/ASTCommon.cpp | 3 + clang/lib/Serialization/ASTReader.cpp | 3 + clang/test/SemaCXX/PR62533.cpp| 2 +- clang/test/SemaTemplate/template-id-expr.cpp | 71 +++ 13 files changed, 120 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0a2..e9a22f04cfe764 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase { CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127191..eb72bf0f866247 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,8 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 500098dd3dab1d..a0feb3a317611e 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1099,6 +1099,8 @@ enum PredefinedTypeIDs { // \brief WebAssembly reference types with auto numeration #define WASM_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID, #include "clang/Basic/WebAssemblyReferenceTypes.def" + + PREDEF_TYPE_UNRESOLVED_TEMPLATE, // Sentinel value. Considered a predefined type but not useable as one. PREDEF_TYPE_LAST_ID }; @@ -1108,7 +1110,7 @@ enum PredefinedTypeIDs { /// /// Type IDs for non-predefined types will start at /// NUM_PREDEF_TYPE_IDs. -const unsigned NUM_PREDEF_TYPE_IDS = 502; +const unsigned NUM_PREDEF_TYPE_IDS = 503; // Ensure we do not overrun the predefined types we reserved // in the enum PredefinedTypeIDs above. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 6ce233704a5885..e9fba116cff559 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1306,6 +1306,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo , // Placeholder type for bound members. InitBuiltinType(BoundMemberTy, BuiltinType::BoundMember); + // Placeholder type for unresolved templates. + InitBuiltinType(UnresolvedTemplateTy, BuiltinType::UnresolvedTemplate); + // Placeholder type for pseudo-objects. InitBuiltinType(PseudoObjectTy, BuiltinType::PseudoObject); diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp index ecc56c13fb7573..4e09b27b0f76cd 100644 --- a/clang/lib/AST/NSAPI.cpp +++ b/clang/lib/AST/NSAPI.cpp @@ -454,6 +454,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const { #define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id: #include "clang/Basic/WebAssemblyReferenceTypes.def" case BuiltinType::BoundMember: + case BuiltinType::UnresolvedTemplate: case BuiltinType::Dependent: case BuiltinType::Overload: case BuiltinType::UnknownAny: diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index cb22c91a12aa89..4751d73184262f 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3381,6 +3381,8 @@ StringRef BuiltinType::getName(const PrintingPolicy ) const { return ""; case BoundMember: return ""; + case UnresolvedTemplate: +return ""; case PseudoObject: return ""; case Dependent: @@ -4673,6 +4675,7 @@ bool