[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-02-07 Thread Jordan Rupprecht via cfe-commits

rupprecht wrote:

Ok, thanks for the quick confirmation!

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-02-07 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@rupprecht This is intended behavior. We previously did not check qualified 
declarations of explicit/partial specializations of class templates for 
redundant qualification & invalid nested-name-specifiers (e.g. ones that begin 
with `decltype`). We do now, hence the new warning. 

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-02-07 Thread Jordan Rupprecht via cfe-commits

rupprecht wrote:

It looks like this caused some new `-Wextra-qualification` warnings 
(playground: https://godbolt.org/z/3MbMjGYET)

```
namespace foo {
template 
struct Z {};

template <>
struct Z {}; // OK

template <>
struct foo::Z {}; // New warning: extra qualification on member 'Z' 
[-Wextra-qualification]

template <>
struct ::foo::Z {}; // New warning: extra qualification on member 'Z' 
[-Wextra-qualification]
}  // namespace foo
```

This doesn't use `template` in the way described in the commit or the release 
notes, so it doesn't seem like an intentional change. But GCC already errors on 
this (and downgrades to a warning with `-fpermissive`), so Clang isn't 
necessarily wrong to start warning about this now. Still, it's possible GCC and 
Clang are both wrong now, so I just want to make sure that's actually a desired 
side effect of this commit.

This behavior change is covered by the test diffs here in 
clang/test/CXX/drs/dr23xx.cpp and 
clang/test/SemaTemplate/class-template-spec.cpp.

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-02-02 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-02-02 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/78595

>From 44689d064a5e4c908c0011532302e9b84e060fab Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 17 Jan 2024 10:13:29 -0500
Subject: [PATCH] [Clang][Sema] Diagnose use of template keyword after
 declarative nested-name-specifiers

---
 clang/docs/ReleaseNotes.rst   |   1 +
 clang/include/clang/AST/TypeLoc.h |   5 +-
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Sema/Sema.h   |   3 +-
 clang/lib/AST/TypeLoc.cpp |   9 +
 clang/lib/Parse/ParseDecl.cpp |   4 +-
 clang/lib/Sema/SemaDecl.cpp   |  49 -
 clang/lib/Sema/SemaDeclCXX.cpp|  14 +-
 clang/lib/Sema/SemaTemplate.cpp   |  17 +-
 clang/lib/Sema/TreeTransform.h|   3 +-
 clang/test/CXX/drs/dr23xx.cpp |   4 +-
 clang/test/CXX/drs/dr7xx.cpp  |   6 +-
 .../temp.class/temp.mem.func/p1.cpp   |   2 +-
 clang/test/CXX/temp/temp.names/p5.cpp | 206 ++
 clang/test/CXX/temp/temp.spec/part.spec.cpp   |   2 +-
 clang/test/SemaCXX/static-assert.cpp  |   2 +-
 .../test/SemaTemplate/class-template-spec.cpp |   8 +-
 17 files changed, 306 insertions(+), 32 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.names/p5.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b5c6fbd32cc91..cd8a82f281f52 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -149,6 +149,7 @@ Improvements to Clang's diagnostics
   prints.
 
 - Clang now diagnoses member template declarations with multiple declarators.
+- Clang now diagnoses use of the ``template`` keyword after declarative nested 
name specifiers.
 
 Improvements to Clang's time-trace
 --
diff --git a/clang/include/clang/AST/TypeLoc.h 
b/clang/include/clang/AST/TypeLoc.h
index b1b38f882d19f..32028e877fc8d 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -189,6 +189,9 @@ class TypeLoc {
   /// pointer types, but not through decltype or typedefs.
   AutoTypeLoc getContainedAutoTypeLoc() const;
 
+  /// Get the SourceLocation of the template keyword (if any).
+  SourceLocation getTemplateKeywordLoc() const;
+
   /// Initializes this to state that every location in this
   /// type is the given location.
   ///
@@ -1691,7 +1694,7 @@ class TemplateSpecializationTypeLoc :
   }
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
-setTemplateKeywordLoc(Loc);
+setTemplateKeywordLoc(SourceLocation());
 setTemplateNameLoc(Loc);
 setLAngleLoc(Loc);
 setRAngleLoc(Loc);
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 21a767cfc5e5c..f76e7a3392183 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8247,6 +8247,9 @@ def err_invalid_declarator_in_block : Error<
   "definition or redeclaration of %0 not allowed inside a block">;
 def err_not_tag_in_scope : Error<
   "no %select{struct|interface|union|class|enum}0 named %1 in %2">;
+def ext_template_after_declarative_nns : ExtWarn<
+"'template' cannot be used after a declarative nested name specifier">,
+InGroup>;
 
 def err_no_typeid_with_fno_rtti : Error<
   "use of typeid requires -frtti">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 7885cf6728b54..3c26003b5bda7 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2960,7 +2960,8 @@ class Sema final {
   bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
   bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name, SourceLocation Loc,
-bool IsTemplateId);
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization);
   void
   diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
 SourceLocation FallbackLoc,
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 66732bba18e2d..b0acb18230875 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -738,3 +738,12 @@ AutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const {
 return AutoTypeLoc();
   return Res.getAs();
 }
+
+SourceLocation TypeLoc::getTemplateKeywordLoc() const {
+  if (const auto TSTL = getAsAdjusted())
+return TSTL.getTemplateKeywordLoc();
+  if (const auto DTSTL =
+  getAsAdjusted())
+return DTSTL.getTemplateKeywordLoc();
+  return SourceLocation();
+}
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index a186253954f68..94696d8e482e5 100644
--- a/clang/l

[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-02-02 Thread Erich Keane via cfe-commits

https://github.com/erichkeane approved this pull request.


https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-02-02 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@erichkeane cor3ntin approved... please take a look when you have time

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-02-01 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/78595

>From 3c211c6fb78f48dc68634e042e94dbe2f33fb999 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 17 Jan 2024 10:13:29 -0500
Subject: [PATCH] [Clang][Sema] Diagnose use of template keyword after
 declarative nested-name-specifiers

---
 clang/docs/ReleaseNotes.rst   |   1 +
 clang/include/clang/AST/TypeLoc.h |   5 +-
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Sema/Sema.h   |   3 +-
 clang/lib/AST/TypeLoc.cpp |   9 +
 clang/lib/Parse/ParseDecl.cpp |   4 +-
 clang/lib/Sema/SemaDecl.cpp   |  49 -
 clang/lib/Sema/SemaDeclCXX.cpp|  14 +-
 clang/lib/Sema/SemaTemplate.cpp   |  17 +-
 clang/lib/Sema/TreeTransform.h|   3 +-
 clang/test/CXX/drs/dr23xx.cpp |   4 +-
 clang/test/CXX/drs/dr7xx.cpp  |   6 +-
 .../temp.class/temp.mem.func/p1.cpp   |   2 +-
 clang/test/CXX/temp/temp.names/p5.cpp | 206 ++
 clang/test/CXX/temp/temp.spec/part.spec.cpp   |   2 +-
 clang/test/SemaCXX/static-assert.cpp  |   2 +-
 .../test/SemaTemplate/class-template-spec.cpp |   8 +-
 17 files changed, 306 insertions(+), 32 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.names/p5.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 53040aa0f9074..b9344f83d6e1f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -149,6 +149,7 @@ Improvements to Clang's diagnostics
   prints.
 
 - Clang now diagnoses member template declarations with multiple declarators.
+- Clang now diagnoses use of the ``template`` keyword after declarative nested 
name specifiers.
 
 Improvements to Clang's time-trace
 --
diff --git a/clang/include/clang/AST/TypeLoc.h 
b/clang/include/clang/AST/TypeLoc.h
index b1b38f882d19f..32028e877fc8d 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -189,6 +189,9 @@ class TypeLoc {
   /// pointer types, but not through decltype or typedefs.
   AutoTypeLoc getContainedAutoTypeLoc() const;
 
+  /// Get the SourceLocation of the template keyword (if any).
+  SourceLocation getTemplateKeywordLoc() const;
+
   /// Initializes this to state that every location in this
   /// type is the given location.
   ///
@@ -1691,7 +1694,7 @@ class TemplateSpecializationTypeLoc :
   }
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
-setTemplateKeywordLoc(Loc);
+setTemplateKeywordLoc(SourceLocation());
 setTemplateNameLoc(Loc);
 setLAngleLoc(Loc);
 setRAngleLoc(Loc);
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7638a7e84c3c0..bee413e6da614 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8241,6 +8241,9 @@ def err_invalid_declarator_in_block : Error<
   "definition or redeclaration of %0 not allowed inside a block">;
 def err_not_tag_in_scope : Error<
   "no %select{struct|interface|union|class|enum}0 named %1 in %2">;
+def ext_template_after_declarative_nns : ExtWarn<
+"'template' cannot be used after a declarative nested name specifier">,
+InGroup>;
 
 def err_no_typeid_with_fno_rtti : Error<
   "use of typeid requires -frtti">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 780a2f2d8ce27..a74511a8cf94b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2960,7 +2960,8 @@ class Sema final {
   bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
   bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name, SourceLocation Loc,
-bool IsTemplateId);
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization);
   void
   diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
 SourceLocation FallbackLoc,
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 66732bba18e2d..b0acb18230875 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -738,3 +738,12 @@ AutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const {
 return AutoTypeLoc();
   return Res.getAs();
 }
+
+SourceLocation TypeLoc::getTemplateKeywordLoc() const {
+  if (const auto TSTL = getAsAdjusted())
+return TSTL.getTemplateKeywordLoc();
+  if (const auto DTSTL =
+  getAsAdjusted())
+return DTSTL.getTemplateKeywordLoc();
+  return SourceLocation();
+}
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index a186253954f68..94696d8e482e5 100644
--- a/clang/l

[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread via cfe-commits

https://github.com/cor3ntin approved this pull request.

LGTM, thanks!

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian edited 
https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@cor3ntin Addressed your comments. I also added the error to a diagnostics 
group (`template-in-declaration-name`)

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/78595

>From 529d16d3509219b9d1cc74c515ec101b1316b6d1 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 17 Jan 2024 10:13:29 -0500
Subject: [PATCH] [Clang][Sema] Diagnose use of template keyword after
 declarative nested-name-specifiers

---
 clang/docs/ReleaseNotes.rst   |   3 +
 clang/include/clang/AST/TypeLoc.h |   5 +-
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Sema/Sema.h   |   3 +-
 clang/lib/AST/TypeLoc.cpp |   9 +
 clang/lib/Parse/ParseDecl.cpp |   4 +-
 clang/lib/Sema/SemaDecl.cpp   |  49 -
 clang/lib/Sema/SemaDeclCXX.cpp|  14 +-
 clang/lib/Sema/SemaTemplate.cpp   |  17 +-
 clang/lib/Sema/TreeTransform.h|   3 +-
 clang/test/CXX/drs/dr23xx.cpp |   4 +-
 clang/test/CXX/drs/dr7xx.cpp  |   6 +-
 .../temp.class/temp.mem.func/p1.cpp   |   2 +-
 clang/test/CXX/temp/temp.names/p5.cpp | 206 ++
 clang/test/CXX/temp/temp.spec/part.spec.cpp   |   2 +-
 clang/test/SemaCXX/static-assert.cpp  |   2 +-
 .../test/SemaTemplate/class-template-spec.cpp |   8 +-
 17 files changed, 308 insertions(+), 32 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.names/p5.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9473867c1f231..798ec8979eb27 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -114,6 +114,9 @@ Improvements to Clang's diagnostics
 - Clang now applies syntax highlighting to the code snippets it
   prints.
 
+- Clang now diagnoses use of the ``template`` keyword after declarative nested 
name specifiers.
+
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/AST/TypeLoc.h 
b/clang/include/clang/AST/TypeLoc.h
index a17b4af13d03f..71a3b5c2d4857 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -189,6 +189,9 @@ class TypeLoc {
   /// pointer types, but not through decltype or typedefs.
   AutoTypeLoc getContainedAutoTypeLoc() const;
 
+  /// Get the SourceLocation of the template keyword (if any).
+  SourceLocation getTemplateKeywordLoc() const;
+
   /// Initializes this to state that every location in this
   /// type is the given location.
   ///
@@ -1688,7 +1691,7 @@ class TemplateSpecializationTypeLoc :
   }
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
-setTemplateKeywordLoc(Loc);
+setTemplateKeywordLoc(SourceLocation());
 setTemplateNameLoc(Loc);
 setLAngleLoc(Loc);
 setRAngleLoc(Loc);
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1c0ebbe4e6834..7c2eb262a70db 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8241,6 +8241,9 @@ def err_invalid_declarator_in_block : Error<
   "definition or redeclaration of %0 not allowed inside a block">;
 def err_not_tag_in_scope : Error<
   "no %select{struct|interface|union|class|enum}0 named %1 in %2">;
+def ext_template_after_declarative_nns : ExtWarn<
+"'template' cannot be used after a declarative nested name specifier">,
+InGroup>;
 
 def err_no_typeid_with_fno_rtti : Error<
   "use of typeid requires -frtti">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 59eab0185ae63..5b8d2e778e9b2 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2962,7 +2962,8 @@ class Sema final {
   bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
   bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name, SourceLocation Loc,
-bool IsTemplateId);
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization);
   void
   diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
 SourceLocation FallbackLoc,
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 66732bba18e2d..b0acb18230875 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -738,3 +738,12 @@ AutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const {
 return AutoTypeLoc();
   return Res.getAs();
 }
+
+SourceLocation TypeLoc::getTemplateKeywordLoc() const {
+  if (const auto TSTL = getAsAdjusted())
+return TSTL.getTemplateKeywordLoc();
+  if (const auto DTSTL =
+  getAsAdjusted())
+return DTSTL.getTemplateKeywordLoc();
+  return SourceLocation();
+}
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index bcbe2d9c635a6..06dcb6de812d3 100644
--- a/clang/lib/Parse/P

[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian edited 
https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/78595

>From ba33d31a3029ab538ae5ddc61609b848ee1261d4 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 17 Jan 2024 10:13:29 -0500
Subject: [PATCH] [Clang][Sema] Diagnose use of template keyword after
 declarative nested-name-specifiers

---
 clang/docs/ReleaseNotes.rst   |   3 +
 clang/include/clang/AST/TypeLoc.h |   2 +-
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Sema/Sema.h   |   3 +-
 clang/lib/Parse/ParseDecl.cpp |   7 +-
 clang/lib/Sema/SemaDecl.cpp   |  59 -
 clang/lib/Sema/SemaDeclCXX.cpp|  14 +-
 clang/lib/Sema/SemaTemplate.cpp   |  17 +-
 clang/lib/Sema/TreeTransform.h|  10 +-
 clang/test/CXX/drs/dr23xx.cpp |   4 +-
 clang/test/CXX/drs/dr7xx.cpp  |   6 +-
 .../temp.class/temp.mem.func/p1.cpp   |   2 +-
 clang/test/CXX/temp/temp.names/p5.cpp | 206 ++
 clang/test/CXX/temp/temp.spec/part.spec.cpp   |   2 +-
 clang/test/SemaCXX/static-assert.cpp  |   2 +-
 .../test/SemaTemplate/class-template-spec.cpp |   8 +-
 16 files changed, 314 insertions(+), 34 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.names/p5.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9473867c1f231..798ec8979eb27 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -114,6 +114,9 @@ Improvements to Clang's diagnostics
 - Clang now applies syntax highlighting to the code snippets it
   prints.
 
+- Clang now diagnoses use of the ``template`` keyword after declarative nested 
name specifiers.
+
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/AST/TypeLoc.h 
b/clang/include/clang/AST/TypeLoc.h
index a17b4af13d03f..42eb748108321 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -1688,7 +1688,7 @@ class TemplateSpecializationTypeLoc :
   }
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
-setTemplateKeywordLoc(Loc);
+setTemplateKeywordLoc(SourceLocation());
 setTemplateNameLoc(Loc);
 setLAngleLoc(Loc);
 setRAngleLoc(Loc);
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1c0ebbe4e6834..7c2eb262a70db 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8241,6 +8241,9 @@ def err_invalid_declarator_in_block : Error<
   "definition or redeclaration of %0 not allowed inside a block">;
 def err_not_tag_in_scope : Error<
   "no %select{struct|interface|union|class|enum}0 named %1 in %2">;
+def ext_template_after_declarative_nns : ExtWarn<
+"'template' cannot be used after a declarative nested name specifier">,
+InGroup>;
 
 def err_no_typeid_with_fno_rtti : Error<
   "use of typeid requires -frtti">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 59eab0185ae63..5b8d2e778e9b2 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2962,7 +2962,8 @@ class Sema final {
   bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
   bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name, SourceLocation Loc,
-bool IsTemplateId);
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization);
   void
   diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
 SourceLocation FallbackLoc,
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index bcbe2d9c635a6..367dd7a92b806 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -6592,12 +6592,15 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
   }
 
   bool HadScope = D.getCXXScopeSpec().isValid();
+  SourceLocation TemplateKWLoc;
   if (ParseUnqualifiedId(D.getCXXScopeSpec(),
  /*ObjectType=*/nullptr,
  /*ObjectHadErrors=*/false,
  /*EnteringContext=*/true,
- /*AllowDestructorName=*/true, 
AllowConstructorName,
- AllowDeductionGuide, nullptr, D.getName()) ||
+ /*AllowDestructorName=*/true,
+ AllowConstructorName,
+ AllowDeductionGuide,
+ &TemplateKWLoc, D.getName()) ||
   // Once we're past the identifier, if the scope was bad, mark the
   // whole declarator bad.
   D.getCXXScopeSpec().isInvalid()) {
diff

[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread Krystian Stasiowski via cfe-commits


@@ -4394,8 +4394,14 @@ NestedNameSpecifierLoc 
TreeTransform::TransformNestedNameSpecifierLoc(
   SS.Adopt(ETL.getQualifierLoc());
   TL = ETL.getNamedTypeLoc();
 }
-SS.Extend(SemaRef.Context, /*FIXME:*/ SourceLocation(), TL,
-  Q.getLocalEndLoc());
+SourceLocation TemplateKWLoc;
+if (const auto TSTL = TL.getAs())
+  TemplateKWLoc = TSTL.getTemplateKeywordLoc();
+else if (const auto DTSTL =
+ TL.getAs())
+  TemplateKWLoc = DTSTL.getTemplateKeywordLoc();

sdkrystian wrote:

@cor3ntin Make it a function where? In `ASTContext`, `TypeLoc`, or as a 
non-member function? `TemplateSpecializationTypeLoc` and 
`DependentTemplateSpecializationTypeLoc` don't have a common base other than 
`TypeLoc`.

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread Krystian Stasiowski via cfe-commits


@@ -3,21 +3,21 @@ template // expected-note{{previous 
template}}
 class X0 {
 public:
   typedef int size_type;
-  
+
   X0(int);
   ~X0();
-  
+
   void f0(const T&, const U&);
-  
+
   T& operator[](int i) const;
-  
+
   void f1(size_type) const;
   void f2(size_type) const;
   void f3(size_type) const;
   void f4() ;
-  
+
   operator T*() const;
-  
+
   T value;
 };
 

sdkrystian wrote:

Oh, whoops. Sure.

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread via cfe-commits


@@ -6327,12 +6331,42 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec 
&SS, DeclContext *DC,
 return false;
   }
 
+  // C++23 [temp.names]p5:
+  //   The keyword template shall not appear immediately after a declarative
+  //   nested-name-specifier.
+  if (TemplateId && TemplateId->TemplateKWLoc.isValid()) {
+Diag(Loc, diag::ext_template_after_declarative_nns)
+<< FixItHint::CreateRemoval(TemplateId->TemplateKWLoc);
+  }
+
+  NestedNameSpecifierLoc SpecLoc(SS.getScopeRep(), SS.location_data());
+  while (SpecLoc.getPrefix()) {
+// C++23 [temp.names]p5:
+//   The keyword template shall not appear immediately after a declarative
+//   nested-name-specifier.
+// FIXME: nested-name-specifiers in friend declarations are declarative,
+// but we don't call diagnoseQualifiedDeclaration for them. We should.

cor3ntin wrote:

Can you add a test for that?

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread via cfe-commits


@@ -3,21 +3,21 @@ template // expected-note{{previous 
template}}
 class X0 {
 public:
   typedef int size_type;
-  
+
   X0(int);
   ~X0();
-  
+
   void f0(const T&, const U&);
-  
+
   T& operator[](int i) const;
-  
+
   void f1(size_type) const;
   void f2(size_type) const;
   void f3(size_type) const;
   void f4() ;
-  
+
   operator T*() const;
-  
+
   T value;
 };
 

cor3ntin wrote:

Can you revert the Whitespace only changes in this file?

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread via cfe-commits


@@ -4394,8 +4394,14 @@ NestedNameSpecifierLoc 
TreeTransform::TransformNestedNameSpecifierLoc(
   SS.Adopt(ETL.getQualifierLoc());
   TL = ETL.getNamedTypeLoc();
 }
-SS.Extend(SemaRef.Context, /*FIXME:*/ SourceLocation(), TL,
-  Q.getLocalEndLoc());
+SourceLocation TemplateKWLoc;
+if (const auto TSTL = TL.getAs())
+  TemplateKWLoc = TSTL.getTemplateKeywordLoc();
+else if (const auto DTSTL =
+ TL.getAs())
+  TemplateKWLoc = DTSTL.getTemplateKeywordLoc();

cor3ntin wrote:

Yes, we should make a function :)

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-30 Thread via cfe-commits


@@ -6327,12 +6331,42 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec 
&SS, DeclContext *DC,
 return false;
   }
 
+  // C++23 [temp.names]p5:
+  //   The keyword template shall not appear immediately after a declarative
+  //   nested-name-specifier.
+  if (TemplateId && TemplateId->TemplateKWLoc.isValid()) {
+Diag(Loc, diag::ext_template_after_declarative_nns)
+<< FixItHint::CreateRemoval(TemplateId->TemplateKWLoc);
+  }
+
+  NestedNameSpecifierLoc SpecLoc(SS.getScopeRep(), SS.location_data());
+  while (SpecLoc.getPrefix()) {
+// C++23 [temp.names]p5:
+//   The keyword template shall not appear immediately after a declarative
+//   nested-name-specifier.

cor3ntin wrote:

I don;t think it make sense to repeat the wording twice

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-26 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/78595

>From 75524a1f443c86787f0605d7890a1caa01c5ebf5 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 17 Jan 2024 10:13:29 -0500
Subject: [PATCH 1/2] [Clang][Sema] Diagnose use of template keyword after
 declarative nested-name-specifiers

---
 clang/include/clang/AST/TypeLoc.h |  2 +-
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/include/clang/Sema/Sema.h   |  3 +-
 clang/lib/Sema/SemaDecl.cpp   | 59 ++--
 clang/lib/Sema/SemaDeclCXX.cpp| 14 ++-
 clang/lib/Sema/SemaTemplate.cpp   | 17 +++-
 clang/lib/Sema/TreeTransform.h| 10 +-
 clang/test/CXX/drs/dr23xx.cpp |  4 +-
 clang/test/CXX/drs/dr7xx.cpp  |  6 +-
 .../temp.class/temp.mem.func/p1.cpp   | 18 ++--
 clang/test/CXX/temp/temp.names/p5.cpp | 94 +++
 clang/test/CXX/temp/temp.spec/part.spec.cpp   |  2 +-
 clang/test/SemaCXX/static-assert.cpp  |  2 +-
 .../test/SemaTemplate/class-template-spec.cpp |  8 +-
 14 files changed, 201 insertions(+), 40 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.names/p5.cpp

diff --git a/clang/include/clang/AST/TypeLoc.h 
b/clang/include/clang/AST/TypeLoc.h
index 04780fdeae3bc10..1d6414f69107198 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -1688,7 +1688,7 @@ class TemplateSpecializationTypeLoc :
   }
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
-setTemplateKeywordLoc(Loc);
+setTemplateKeywordLoc(SourceLocation());
 setTemplateNameLoc(Loc);
 setLAngleLoc(Loc);
 setRAngleLoc(Loc);
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 649de9f47c46195..41c281b9e26064b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8233,6 +8233,8 @@ def err_invalid_declarator_in_block : Error<
   "definition or redeclaration of %0 not allowed inside a block">;
 def err_not_tag_in_scope : Error<
   "no %select{struct|interface|union|class|enum}0 named %1 in %2">;
+def ext_template_after_declarative_nns : ExtWarn<
+"'template' cannot be used after a declarative nested name specifier">;
 
 def err_no_typeid_with_fno_rtti : Error<
   "use of typeid requires -frtti">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1f1cbd11ff73581..96ccf8847b4b8dc 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2915,7 +2915,8 @@ class Sema final {
   bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
   bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name, SourceLocation Loc,
-bool IsTemplateId);
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization);
   void
   diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
 SourceLocation FallbackLoc,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f9bf1d14bdc4f68..f68e21738d10e83 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6264,13 +6264,17 @@ bool Sema::DiagnoseClassNameShadow(DeclContext *DC,
 ///
 /// \param Loc The location of the name of the entity being declared.
 ///
-/// \param IsTemplateId Whether the name is a (simple-)template-id, and thus
-/// we're declaring an explicit / partial specialization / instantiation.
+/// \param IsMemberSpecialization Whether we are declaring a member
+/// specialization.
+///
+/// \param TemplateId The template-id, if any.
 ///
 /// \returns true if we cannot safely recover from this error, false otherwise.
 bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name,
-SourceLocation Loc, bool IsTemplateId) 
{
+SourceLocation Loc,
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization) {
   DeclContext *Cur = CurContext;
   while (isa(Cur) || isa(Cur))
 Cur = Cur->getParent();
@@ -6299,7 +6303,7 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, 
DeclContext *DC,
   // Check whether the qualifying scope encloses the scope of the original
   // declaration. For a template-id, we perform the checks in
   // CheckTemplateSpecializationScope.
-  if (!Cur->Encloses(DC) && !IsTemplateId) {
+  if (!Cur->Encloses(DC) && !(TemplateId || IsMemberSpecialization)) {
 if (Cur->isRecord())
   Diag(Loc, diag::err_member_qualification)
 << Nam

[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-19 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@cor3ntin I changed the diagnostic to a pedantic warning and added a release 
note. 

> I wonder if we should add tests for 
> https://cplusplus.github.io/CWG/issues/1707.html in this patch.

We don't check for the template keyword when parsing an 
_elaborated-type-specifier_ without a _nested-name-specifier_, so such a 
declaration is parsed as an unnamed class. I feel that it's beyond the scope of 
this PR anyways, as this is only concerned with qualified declarations. 

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-19 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/78595

>From f72b5e65817e9c25ec0fcabbf0a6bf684066a046 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 17 Jan 2024 10:13:29 -0500
Subject: [PATCH 1/2] [Clang][Sema] Diagnose use of template keyword after
 declarative nested-name-specifiers

---
 clang/include/clang/AST/TypeLoc.h |  2 +-
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/include/clang/Sema/Sema.h   |  3 +-
 clang/lib/Sema/SemaDecl.cpp   | 59 ++--
 clang/lib/Sema/SemaDeclCXX.cpp| 14 ++-
 clang/lib/Sema/SemaTemplate.cpp   | 17 +++-
 clang/lib/Sema/TreeTransform.h| 10 +-
 clang/test/CXX/drs/dr23xx.cpp |  4 +-
 clang/test/CXX/drs/dr7xx.cpp  |  6 +-
 .../temp.class/temp.mem.func/p1.cpp   | 18 ++--
 clang/test/CXX/temp/temp.names/p5.cpp | 94 +++
 clang/test/CXX/temp/temp.spec/part.spec.cpp   |  2 +-
 clang/test/SemaCXX/static-assert.cpp  |  2 +-
 .../test/SemaTemplate/class-template-spec.cpp |  8 +-
 14 files changed, 201 insertions(+), 40 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.names/p5.cpp

diff --git a/clang/include/clang/AST/TypeLoc.h 
b/clang/include/clang/AST/TypeLoc.h
index 471deb14aba51f..4b95e2d0a7da41 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -1684,7 +1684,7 @@ class TemplateSpecializationTypeLoc :
   }
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
-setTemplateKeywordLoc(Loc);
+setTemplateKeywordLoc(SourceLocation());
 setTemplateNameLoc(Loc);
 setLAngleLoc(Loc);
 setRAngleLoc(Loc);
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 03b0122d1c08f7..a5aedd45452e44 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8223,6 +8223,8 @@ def err_invalid_declarator_in_block : Error<
   "definition or redeclaration of %0 not allowed inside a block">;
 def err_not_tag_in_scope : Error<
   "no %select{struct|interface|union|class|enum}0 named %1 in %2">;
+def ext_template_after_declarative_nns : ExtWarn<
+"'template' cannot be used after a declarative nested name specifier">;
 
 def err_no_typeid_with_fno_rtti : Error<
   "use of typeid requires -frtti">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 0db39333b0ee34..c2f2e9ba1d304b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2915,7 +2915,8 @@ class Sema final {
   bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
   bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name, SourceLocation Loc,
-bool IsTemplateId);
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization);
   void
   diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
 SourceLocation FallbackLoc,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index cbb8ed8ce34d1b..f8d12ca0b1c7c8 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6264,13 +6264,17 @@ bool Sema::DiagnoseClassNameShadow(DeclContext *DC,
 ///
 /// \param Loc The location of the name of the entity being declared.
 ///
-/// \param IsTemplateId Whether the name is a (simple-)template-id, and thus
-/// we're declaring an explicit / partial specialization / instantiation.
+/// \param IsMemberSpecialization Whether we are declaring a member
+/// specialization.
+///
+/// \param TemplateId The template-id, if any.
 ///
 /// \returns true if we cannot safely recover from this error, false otherwise.
 bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name,
-SourceLocation Loc, bool IsTemplateId) 
{
+SourceLocation Loc,
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization) {
   DeclContext *Cur = CurContext;
   while (isa(Cur) || isa(Cur))
 Cur = Cur->getParent();
@@ -6299,7 +6303,7 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, 
DeclContext *DC,
   // Check whether the qualifying scope encloses the scope of the original
   // declaration. For a template-id, we perform the checks in
   // CheckTemplateSpecializationScope.
-  if (!Cur->Encloses(DC) && !IsTemplateId) {
+  if (!Cur->Encloses(DC) && !(TemplateId || IsMemberSpecialization)) {
 if (Cur->isRecord())
   Diag(Loc, diag::err_member_qualification)
 << Name << SS.

[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-19 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/78595

>From f72b5e65817e9c25ec0fcabbf0a6bf684066a046 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 17 Jan 2024 10:13:29 -0500
Subject: [PATCH] [Clang][Sema] Diagnose use of template keyword after
 declarative nested-name-specifiers

---
 clang/include/clang/AST/TypeLoc.h |  2 +-
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/include/clang/Sema/Sema.h   |  3 +-
 clang/lib/Sema/SemaDecl.cpp   | 59 ++--
 clang/lib/Sema/SemaDeclCXX.cpp| 14 ++-
 clang/lib/Sema/SemaTemplate.cpp   | 17 +++-
 clang/lib/Sema/TreeTransform.h| 10 +-
 clang/test/CXX/drs/dr23xx.cpp |  4 +-
 clang/test/CXX/drs/dr7xx.cpp  |  6 +-
 .../temp.class/temp.mem.func/p1.cpp   | 18 ++--
 clang/test/CXX/temp/temp.names/p5.cpp | 94 +++
 clang/test/CXX/temp/temp.spec/part.spec.cpp   |  2 +-
 clang/test/SemaCXX/static-assert.cpp  |  2 +-
 .../test/SemaTemplate/class-template-spec.cpp |  8 +-
 14 files changed, 201 insertions(+), 40 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.names/p5.cpp

diff --git a/clang/include/clang/AST/TypeLoc.h 
b/clang/include/clang/AST/TypeLoc.h
index 471deb14aba51f..4b95e2d0a7da41 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -1684,7 +1684,7 @@ class TemplateSpecializationTypeLoc :
   }
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
-setTemplateKeywordLoc(Loc);
+setTemplateKeywordLoc(SourceLocation());
 setTemplateNameLoc(Loc);
 setLAngleLoc(Loc);
 setRAngleLoc(Loc);
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 03b0122d1c08f7..a5aedd45452e44 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8223,6 +8223,8 @@ def err_invalid_declarator_in_block : Error<
   "definition or redeclaration of %0 not allowed inside a block">;
 def err_not_tag_in_scope : Error<
   "no %select{struct|interface|union|class|enum}0 named %1 in %2">;
+def ext_template_after_declarative_nns : ExtWarn<
+"'template' cannot be used after a declarative nested name specifier">;
 
 def err_no_typeid_with_fno_rtti : Error<
   "use of typeid requires -frtti">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 0db39333b0ee34..c2f2e9ba1d304b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2915,7 +2915,8 @@ class Sema final {
   bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
   bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name, SourceLocation Loc,
-bool IsTemplateId);
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization);
   void
   diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
 SourceLocation FallbackLoc,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index cbb8ed8ce34d1b..f8d12ca0b1c7c8 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6264,13 +6264,17 @@ bool Sema::DiagnoseClassNameShadow(DeclContext *DC,
 ///
 /// \param Loc The location of the name of the entity being declared.
 ///
-/// \param IsTemplateId Whether the name is a (simple-)template-id, and thus
-/// we're declaring an explicit / partial specialization / instantiation.
+/// \param IsMemberSpecialization Whether we are declaring a member
+/// specialization.
+///
+/// \param TemplateId The template-id, if any.
 ///
 /// \returns true if we cannot safely recover from this error, false otherwise.
 bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name,
-SourceLocation Loc, bool IsTemplateId) 
{
+SourceLocation Loc,
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization) {
   DeclContext *Cur = CurContext;
   while (isa(Cur) || isa(Cur))
 Cur = Cur->getParent();
@@ -6299,7 +6303,7 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, 
DeclContext *DC,
   // Check whether the qualifying scope encloses the scope of the original
   // declaration. For a template-id, we perform the checks in
   // CheckTemplateSpecializationScope.
-  if (!Cur->Encloses(DC) && !IsTemplateId) {
+  if (!Cur->Encloses(DC) && !(TemplateId || IsMemberSpecialization)) {
 if (Cur->isRecord())
   Diag(Loc, diag::err_member_qualification)
 << Name << SS.getR

[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-19 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/78595

>From c07119d8e85e4bd9849e8d0b5dc8edb5384d9b91 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 17 Jan 2024 10:13:29 -0500
Subject: [PATCH] [Clang][Sema] Diagnose use of template keyword after
 declarative nested-name-specifiers

---
 clang/include/clang/AST/TypeLoc.h |  2 +-
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/include/clang/Sema/Sema.h   |  3 +-
 clang/lib/Sema/SemaDecl.cpp   | 59 ++--
 clang/lib/Sema/SemaDeclCXX.cpp| 14 ++-
 clang/lib/Sema/SemaTemplate.cpp   | 17 +++-
 clang/lib/Sema/TreeTransform.h| 10 +-
 clang/test/CXX/drs/dr23xx.cpp |  4 +-
 clang/test/CXX/drs/dr7xx.cpp  |  6 +-
 .../temp.class/temp.mem.func/p1.cpp   | 18 ++--
 clang/test/CXX/temp/temp.names/p5.cpp | 94 +++
 clang/test/CXX/temp/temp.spec/part.spec.cpp   |  2 +-
 clang/test/SemaCXX/static-assert.cpp  |  2 +-
 .../test/SemaTemplate/class-template-spec.cpp |  8 +-
 14 files changed, 201 insertions(+), 40 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.names/p5.cpp

diff --git a/clang/include/clang/AST/TypeLoc.h 
b/clang/include/clang/AST/TypeLoc.h
index 471deb14aba51f..4b95e2d0a7da41 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -1684,7 +1684,7 @@ class TemplateSpecializationTypeLoc :
   }
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
-setTemplateKeywordLoc(Loc);
+setTemplateKeywordLoc(SourceLocation());
 setTemplateNameLoc(Loc);
 setLAngleLoc(Loc);
 setRAngleLoc(Loc);
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 03b0122d1c08f7..a5aedd45452e44 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8223,6 +8223,8 @@ def err_invalid_declarator_in_block : Error<
   "definition or redeclaration of %0 not allowed inside a block">;
 def err_not_tag_in_scope : Error<
   "no %select{struct|interface|union|class|enum}0 named %1 in %2">;
+def ext_template_after_declarative_nns : ExtWarn<
+"'template' cannot be used after a declarative nested name specifier">;
 
 def err_no_typeid_with_fno_rtti : Error<
   "use of typeid requires -frtti">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 0db39333b0ee34..c2f2e9ba1d304b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2915,7 +2915,8 @@ class Sema final {
   bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
   bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name, SourceLocation Loc,
-bool IsTemplateId);
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization);
   void
   diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
 SourceLocation FallbackLoc,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index cbb8ed8ce34d1b..f8d12ca0b1c7c8 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6264,13 +6264,17 @@ bool Sema::DiagnoseClassNameShadow(DeclContext *DC,
 ///
 /// \param Loc The location of the name of the entity being declared.
 ///
-/// \param IsTemplateId Whether the name is a (simple-)template-id, and thus
-/// we're declaring an explicit / partial specialization / instantiation.
+/// \param IsMemberSpecialization Whether we are declaring a member
+/// specialization.
+///
+/// \param TemplateId The template-id, if any.
 ///
 /// \returns true if we cannot safely recover from this error, false otherwise.
 bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
 DeclarationName Name,
-SourceLocation Loc, bool IsTemplateId) 
{
+SourceLocation Loc,
+TemplateIdAnnotation *TemplateId,
+bool IsMemberSpecialization) {
   DeclContext *Cur = CurContext;
   while (isa(Cur) || isa(Cur))
 Cur = Cur->getParent();
@@ -6299,7 +6303,7 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, 
DeclContext *DC,
   // Check whether the qualifying scope encloses the scope of the original
   // declaration. For a template-id, we perform the checks in
   // CheckTemplateSpecializationScope.
-  if (!Cur->Encloses(DC) && !IsTemplateId) {
+  if (!Cur->Encloses(DC) && !(TemplateId || IsMemberSpecialization)) {
 if (Cur->isRecord())
   Diag(Loc, diag::err_member_qualification)
 << Name << SS.getR

[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-18 Thread Krystian Stasiowski via cfe-commits


@@ -182,8 +182,8 @@ struct Bad2 { int a, b; };
 } // namespace dr2386
 namespace std {
 template  struct tuple_size;
-template <> struct std::tuple_size {};

sdkrystian wrote:

It is, yes

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-18 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll edited 
https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-18 Thread Vlad Serebrennikov via cfe-commits


@@ -182,8 +182,8 @@ struct Bad2 { int a, b; };
 } // namespace dr2386
 namespace std {
 template  struct tuple_size;
-template <> struct std::tuple_size {};

Endilll wrote:

Is this warning emitted if we spell it `::std::tuple)size`?

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-18 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@cor3ntin Pedantic warning would probably be best as other implementations are 
not great at diagnosing this

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-18 Thread Krystian Stasiowski via cfe-commits


@@ -182,8 +182,8 @@ struct Bad2 { int a, b; };
 } // namespace dr2386
 namespace std {
 template  struct tuple_size;
-template <> struct std::tuple_size {};

sdkrystian wrote:

@Endilll if left unchanged this will result in a warning about redundant 
qualification, which I don't think is the point of the test... alternatively I 
can add `// expected-warning {{extra qualification on member}}`

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-18 Thread via cfe-commits

cor3ntin wrote:

Thank for this patch 

I think this might be better done as a pedantic warning.
IE, I am concerned that this could break existing code, similarly to 
https://github.com/llvm/llvm-project/issues/78031#issuecomment-1891475606

I wonder if we should add tests for 
https://cplusplus.github.io/CWG/issues/1707.html in this patch.

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-18 Thread Vlad Serebrennikov via cfe-commits


@@ -182,8 +182,8 @@ struct Bad2 { int a, b; };
 } // namespace dr2386
 namespace std {
 template  struct tuple_size;
-template <> struct std::tuple_size {};

Endilll wrote:

Is this a really necessary change?

https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose use of template keyword after declarative nested-name-specifiers (PR #78595)

2024-01-18 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian edited 
https://github.com/llvm/llvm-project/pull/78595
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits