[all-commits] [llvm/llvm-project] 9a88aa: [Clang][Sema] Diagnose variable template explicit ...

Krystian Stasiowski via All-commits all-commits at lists.llvm.org
Tue Jun 18 10:40:52 PDT 2024


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 9a88aa0e2b6d09c7c7932e14224632b2033ad403
      https://github.com/llvm/llvm-project/commit/9a88aa0e2b6d09c7c7932e14224632b2033ad403
  Author: Krystian Stasiowski <sdkrystian at gmail.com>
  Date:   2024-06-18 (Tue, 18 Jun 2024)

  Changed paths:
    M clang/docs/ReleaseNotes.rst
    M clang/include/clang/Basic/DiagnosticSemaKinds.td
    M clang/lib/Parse/ParseDeclCXX.cpp
    M clang/lib/Sema/DeclSpec.cpp
    M clang/lib/Sema/SemaDecl.cpp
    M clang/lib/Sema/SemaDeclCXX.cpp
    M clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp
    M clang/test/CXX/drs/cwg7xx.cpp
    M clang/test/CXX/temp/temp.decls/temp.mem/p2.cpp
    M clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
    M clang/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
    M clang/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
    A clang/test/CXX/temp/temp.spec/temp.expl.spec/p2-20.cpp
    M clang/test/Modules/Inputs/redecl-templates/a.h
    M clang/test/Modules/redecl-templates.cpp
    M clang/test/PCH/cxx-templates.h
    M clang/test/PCH/cxx1y-variable-templates.cpp
    M clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
    M clang/test/SemaTemplate/explicit-specialization-member.cpp
    M clang/test/SemaTemplate/nested-template.cpp

  Log Message:
  -----------
  [Clang][Sema] Diagnose variable template explicit specializations with storage-class-specifiers (#93873)

According to [temp.expl.spec] p2:
> The declaration in an _explicit-specialization_ shall not be an
_export-declaration_. An explicit specialization shall not use a
_storage-class-specifier_ other than `thread_local`.

Clang partially implements this, but a number of issues exist:
1. We don't diagnose class scope explicit specializations of variable
templates with _storage-class-specifiers_, e.g.
    ```
    struct A
    {
        template<typename T>
        static constexpr int x = 0;

        template<>
static constexpr int x<void> = 1; // ill-formed, but clang accepts
    };
    ````
2. We incorrectly reject class scope explicit specializations of
variable templates when `static` is not used, e.g.
    ```
    struct A
    {
        template<typename T>
        static constexpr int x = 0;

        template<>
constexpr int x<void> = 1; // error: non-static data member cannot be
constexpr; did you intend to make it static?
    };
    ````
3. We don't diagnose dependent class scope explicit specializations of
function templates with storage class specifiers, e.g.
    ```
    template<typename T>
    struct A
    {
        template<typename U>
        static void f();

        template<>
        static void f<int>(); // ill-formed, but clang accepts
    };
    ````

This patch addresses these issues as follows:
- # 1 is fixed by issuing a diagnostic when an explicit
specialization of a variable template has storage class specifier
- # 2 is fixed by considering any non-function declaration with any
template parameter lists at class scope to be a static data member. This
also allows for better error recovery (it's more likely the user
intended to declare a variable template than a "field template").
- # 3 is fixed by checking whether a function template explicit
specialization has a storage class specifier even when the primary
template is not yet known.

One thing to note is that it would be far simpler to diagnose this when
parsing the _decl-specifier-seq_, but such an implementation would
necessitate a refactor of `ParsedTemplateInfo` which I believe to be
outside the scope of this patch.



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list