Clang error: expected 'auto' or 'decltype(auto)' after concept name (err_placeholder_expected_auto_or_decltype_auto)

From emmtrix Wiki
Jump to navigation Jump to search
Text error: expected 'auto' or 'decltype(auto)' after concept name (since 10.0)
Type Error
Category Concepts Issue (since 10.0)
Internal Id err_placeholder_expected_auto_or_decltype_auto (since 10.0)
Internal Message expected 'auto' or 'decltype(auto)' after concept name (since 10.0)
Regular Expression (?:error|fatal error)\: expected 'auto' or 'decltype\(auto\)' after concept name
First Commit 2019-10-09 739b410f1ff5 Add a warning, flags and pragmas to limit the number of pre-processor tokens in a translation unit

Description

The error is issued by the Clang compiler when it encounters a situation where a concept name is used without the expected follow-up of either auto or decltype(auto). This typically occurs in the context of a template or a concept definition, where the language syntax requires explicitly stating that the type is to be deduced. Concepts in C++ are a way to specify template requirements, and when a concept is used to specify the type of a variable or to constrain a template, the actual type that satisfies the concept must be automatically deduced by the compiler. However, for this deduction process to be triggered, the keyword auto or the decltype(auto) syntax must be used immediately after the concept name. This requirement ensures that the compiler correctly interprets the concept as applying to the type that is to be deduced, rather than as an independent type or template parameter. Failure to include auto or decltype(auto) after a concept name results in this error, as it prevents the compiler from understanding the intended use of the concept, thus leading to a syntax error.  
AI Generated

Example

In the following example, a C++ concept named C is defined to require that a type T has a nested type named type. This concept is then incorrectly used in an attempt to declare a variable c of type C<int>. However, the syntax for the declaration of variable c is incorrect because it lacks the keyword auto following the concept name C, which is necessary for concept-based type deduction. Consequently, multiple errors are emitted by the compiler. The first error points out the absence of auto or decltype(auto) following the concept name. The second error indicates that an initializer is required for the variable c due to its deduced type. The third error emerges because of the compiler's confusion over c's type, mistaking the concept name for a type itself, which leads to the error that c is not recognized as a class, namespace, or enumeration. Finally, a note is provided, reiterating that the declaration of c is the source of the issues.  
AI Generated


Flags -xc++ -std=c++2a

[Try out in Compiler Explorer]

Source
// Concept definition with a template
template<typename T>
concept C = requires { typename T::type; };

void f() {
  // Incorrect usage of concept: missing 'auto' after concept name
  C<int> c;
  typename c::type;
}
Compiler Output
<source>:7:3: error: expected 'auto' or 'decltype(auto)' after concept name
<source>:7:10: error: declaration of variable 'c' with deduced type 'C<int> auto' requires an initializer
<source>:8:12: error: 'c' is not a class, namespace, or enumeration
<source>:7:10: note: 'c' declared here


Clang Internals (17.0.6)

Git Commit Message

Add a warning, flags and pragmas to limit the number of pre-processor tokens in a translation unit

See
https://docs.google.com/document/d/1xMkTZMKx9llnMPgso0jrx3ankI4cv60xeZ0y4ksf4wc/preview
for background discussion.

This adds a warning, flags and pragmas to limit the number of
pre-processor tokens either at a certain point in a translation unit, or
overall.

The idea is that this would allow projects to limit the size of certain
widely included headers, or for translation units overall, as a way to
insert backstops for header bloat and prevent compile-time regressions.

Differential revision: https://reviews.llvm.org/D72703

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Parse/ParseDecl.cpp (line 3799)

/// ParseDeclarationSpecifiers
///       declaration-specifiers: [C99 6.7]
///         storage-class-specifier declaration-specifiers[opt]
///         type-specifier declaration-specifiers[opt]
/// [C99]   function-specifier declaration-specifiers[opt]
/// [C11]   alignment-specifier declaration-specifiers[opt]
/// [GNU]   attributes declaration-specifiers[opt]
/// [Clang] '__module_private__' declaration-specifiers[opt]
/// [ObjC1] '__kindof' declaration-specifiers[opt]
///
///       storage-class-specifier: [C99 6.7.1]
///         'typedef'
///         'extern'
///         'static'
///         'auto'
///         'register'
/// [C++]   'mutable'
/// [C++11] 'thread_local'
/// [C11]   '_Thread_local'
/// [GNU]   '__thread'
///       function-specifier: [C99 6.7.4]
/// [C99]   'inline'
/// [C++]   'virtual'
/// [C++]   'explicit'
/// [OpenCL] '__kernel'
///       'friend': [C++ dcl.friend]
///       'constexpr': [C++0x dcl.constexpr]
void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS, DeclSpecContext DSContext, LateParsedAttrList *LateAttrs, ImplicitTypenameContext AllowImplicitTypename) {
  // ...
  while (true) {
    // ...
    case tok::annot_template_id: {
      // ...
      if (TemplateId->Kind == TNK_Concept_template) {
        // ...
        // Any of the following tokens are likely the start of the user
        // forgetting 'auto' or 'decltype(auto)', so diagnose.
        // Note: if updating this list, please make sure we update
        // isCXXDeclarationSpecifier's check for IsPlaceholderSpecifier to have
        // a matching list.
        if (NextToken().isOneOf(tok::identifier, tok::kw_const, tok::kw_volatile, tok::kw_restrict, tok::amp, tok::ampamp)) {
          Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto) << FixItHint::CreateInsertion(NextToken().getLocation(), "auto");

clang/lib/Parse/ParseDecl.cpp (line 3823)

/// ParseDeclarationSpecifiers
///       declaration-specifiers: [C99 6.7]
///         storage-class-specifier declaration-specifiers[opt]
///         type-specifier declaration-specifiers[opt]
/// [C99]   function-specifier declaration-specifiers[opt]
/// [C11]   alignment-specifier declaration-specifiers[opt]
/// [GNU]   attributes declaration-specifiers[opt]
/// [Clang] '__module_private__' declaration-specifiers[opt]
/// [ObjC1] '__kindof' declaration-specifiers[opt]
///
///       storage-class-specifier: [C99 6.7.1]
///         'typedef'
///         'extern'
///         'static'
///         'auto'
///         'register'
/// [C++]   'mutable'
/// [C++11] 'thread_local'
/// [C11]   '_Thread_local'
/// [GNU]   '__thread'
///       function-specifier: [C99 6.7.4]
/// [C99]   'inline'
/// [C++]   'virtual'
/// [C++]   'explicit'
/// [OpenCL] '__kernel'
///       'friend': [C++ dcl.friend]
///       'constexpr': [C++0x dcl.constexpr]
void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS, DeclSpecContext DSContext, LateParsedAttrList *LateAttrs, ImplicitTypenameContext AllowImplicitTypename) {
  // ...
  while (true) {
    // ...
    case tok::annot_template_id: {
      // ...
      if (TemplateId->Kind == TNK_Concept_template) {
        // ...
        if (TryConsumeToken(tok::kw_decltype)) {
          // ...
          if (Tracker.consumeOpen()) {
          // ...
          } else {
            if (!TryConsumeToken(tok::kw_auto)) {
              // ...
              Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto) << FixItHint::CreateReplacement(SourceRange(AutoLoc, Tok.getLocation()), "auto");

Triggered in Clang Tests

This section lists all internal Clang test cases that trigger the diagnostic.

clang/test/Parser/cxx2a-placeholder-type-constraint.cpp

  • clang/test/Parser/cxx2a-placeholder-type-constraint.cpp:30:4: error: expected 'auto' or 'decltype(auto)' after concept name
  • clang/test/Parser/cxx2a-placeholder-type-constraint.cpp:32:4: error: expected 'auto' or 'decltype(auto)' after concept name
  • clang/test/Parser/cxx2a-placeholder-type-constraint.cpp:34:4: error: expected 'auto' or 'decltype(auto)' after concept name
  • clang/test/Parser/cxx2a-placeholder-type-constraint.cpp:36:4: error: expected 'auto' or 'decltype(auto)' after concept name
  • clang/test/Parser/cxx2a-placeholder-type-constraint.cpp:40:18: error: expected 'auto' or 'decltype(auto)' after concept name
  • clang/test/Parser/cxx2a-placeholder-type-constraint.cpp:45:11: error: expected 'auto' or 'decltype(auto)' after concept name
  • clang/test/Parser/cxx2a-placeholder-type-constraint.cpp:48:17: error: expected 'auto' or 'decltype(auto)' after concept name