Clang error: A does not support the 'B' ... (err_opencl_unknown_type_specifier)

From emmtrix Wiki
Jump to navigation Jump to search
Text
error: A does not support the 'B'
type qualifier
storage class specifier

(since 14.0)

error:
OpenCL C
C++ for OpenCL
version B does not support the 'C'
type qualifier
storage class specifier

(9.0 - 13.0)

error: OpenCL
C
C++
version B does not support the 'C'
type qualifier
storage class specifier

(7.0 - 8.0)

error: OpenCL version A does not support the 'B'
type qualifier
storage class specifier

(until 6.0)

Type Error
Category None (since 8.0)
Semantic Issue (until 7.1)
Internal Id err_opencl_unknown_type_specifier
Internal Message %0 does not support the '%1' %select{type qualifier|storage class specifier}2 (since 14.0)
%select{OpenCL C|C++ for OpenCL}0 version %1 does not support the '%2' %select{type qualifier|storage class specifier}3 (9.0 - 13.0)
OpenCL %select{C|C++}0 version %1 does not support the '%2' %select{type qualifier|storage class specifier}3 (7.0 - 8.0)
OpenCL version %0 does not support the '%1' %select{type qualifier|storage class specifier}2 (until 6.0)
Regular Expression (?:error|fatal error)\: (.*?) does not support the '(.*?)' (?:type qualifier|storage class specifier)
First Commit 2014-11-26 2c8dcfbae603 [OpenCL] Generic address space has been added in OpenCL v2.0.

Description

The error is issued by the Clang compiler when it encounters a declaration or use of a type qualifier or storage class specifier that is not supported by the target language version, particularly in OpenCL and C++ for OpenCL. This situation often arises due to discrepancies between language specifications and the version the compiler is targeting. For instance, certain type qualifiers or storage class specifiers may not be available in all versions of OpenCL or C++ for OpenCL. The diagnostic message provides specific details about what is not supported and in which language version the support issue arises.

The error serves as an indication that the code may be using a feature not available in the specified version of the language, potentially leading to portability issues or incompatibility with the desired language standard. The compiler identifies the problematic type qualifier or storage class specifier and indicates the language version where the support issue is detected. Each error message specifically outlines whether it's a "type qualifier" or a "storage class specifier" that the identified language version does not support.

Understanding the differences in language version specifications and ensuring compatibility with the desired version is crucial for resolving these errors. Developers may need to modify their code or adjust compiler flags to target a different version of the language that supports the desired features.

 
AI Generated

Example

In the following example, a kernel function named test is defined for use in an OpenCL C program. The function takes a pointer to an integer array in the global address space as its parameter. Inside the function, an integer x is initialized to 42, and a lambda expression is used to create a lambda function l. This lambda captures x by value and attempts to assign its address to a pointer to const int. The lambda is then called within the function. However, the use of auto for the lambda's type triggers an error because the auto storage class specifier is not supported in the specified version of OpenCL C (1.2).

Additionally, other errors are detected related to missing type specifiers, the expectation of an expression, and the misuse of an integer value as a function or function pointer. These errors highlight the strict type requirements and the limitations on the use of auto and lambda expressions in the targeted OpenCL C version.

 
AI Generated


Flags -xcl

[Try out in Compiler Explorer]

Source
__kernel void test(__global int* d) {
  int x = 42; // Define an integer
  auto l = [=]() { const int* p = &x; }; // 'auto' not supported
  l(); // Call lambda
}
Compiler Output
<source>:3:3: error: OpenCL C version 1.2 does not support the 'auto' storage class specifier
<source>:3:8: error: type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int]
<source>:3:12: error: expected expression
<source>:4:4: error: called object type 'int' is not a function or function pointer


Clang Internals (17.0.6)

Git Commit Message

[OpenCL] Generic address space has been added in OpenCL v2.0.

To support it in the frontend, the following has been added:  
- generic address space type attribute;
- documentation for the OpenCL address space attributes;
- parsing of __generic(generic) keyword;
- test code for the parser and diagnostics.

llvm-svn: 222831

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 4293)

/// 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::kw_pipe:
      if (!getLangOpts().OpenCL || getLangOpts().getOpenCLCompatibleVersion() < 200) {
      // ...
      } else if (!getLangOpts().OpenCLPipes) {
        DiagID = diag::err_opencl_unknown_type_specifier;

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

#include "clang/Basic/TransformTypeTraits.def"
    // ...
    // OpenCL address space qualifiers:
    case tok::kw___generic:
      // generic address space is introduced only in OpenCL v2.0
      // see OpenCL C Spec v2.0 s6.5.5
      // OpenCL v3.0 introduces __opencl_c_generic_address_space
      // feature macro to indicate if generic address space is supported
      if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
        DiagID = diag::err_opencl_unknown_type_specifier;

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

#include "clang/Basic/TransformTypeTraits.def"
    // ...
    // If the specifier wasn't legal, issue a diagnostic.
    if (isInvalid) {
      // ...
      else if (DiagID == diag::err_opencl_unknown_type_specifier) {

clang/lib/Sema/DeclSpec.cpp (line 645)

bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy) {
  // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class
  // specifiers are not supported.
  // It seems sensible to prohibit private_extern too
  // The cl_clang_storage_class_specifiers extension enables support for
  // these storage-class specifiers.
  // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class
  // specifiers are not supported."
  if (S.getLangOpts().OpenCL && !S.getOpenCLOptions().isAvailableOption("cl_clang_storage_class_specifiers", S.getLangOpts())) {
    // ...
    case SCS_extern:
    case SCS_private_extern:
    case SCS_static:
      if (S.getLangOpts().getOpenCLCompatibleVersion() < 120) {
        DiagID = diag::err_opencl_unknown_type_specifier;

clang/lib/Sema/DeclSpec.cpp (line 652)

bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy) {
  // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class
  // specifiers are not supported.
  // It seems sensible to prohibit private_extern too
  // The cl_clang_storage_class_specifiers extension enables support for
  // these storage-class specifiers.
  // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class
  // specifiers are not supported."
  if (S.getLangOpts().OpenCL && !S.getOpenCLOptions().isAvailableOption("cl_clang_storage_class_specifiers", S.getLangOpts())) {
    // ...
    case SCS_auto:
    case SCS_register:
      DiagID = diag::err_opencl_unknown_type_specifier;

clang/lib/Sema/SemaDecl.cpp (line 7865)

NamedDecl *Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists, bool &AddToScope, ArrayRef<BindingDecl *> Bindings) {
  // ...
  if (getLangOpts().OpenCL) {
    // ...
    if (TSC != TSCS_unspecified) {
      Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), diag::err_opencl_unknown_type_specifier) << getLangOpts().getOpenCLVersionString() << DeclSpec::getSpecifierName(TSC) << 1;

Triggered in Clang Tests

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

clang/test/Parser/opencl-storage-class.cl

  • clang/test/Parser/opencl-storage-class.cl:5:3: error: OpenCL C version 1.0 does not support the 'static' storage class specifier
  • clang/test/Parser/opencl-storage-class.cl:6:3: error: OpenCL C version 1.0 does not support the 'register' storage class specifier
  • clang/test/Parser/opencl-storage-class.cl:7:3: error: OpenCL C version 1.0 does not support the 'extern' storage class specifier
  • clang/test/Parser/opencl-storage-class.cl:8:3: error: OpenCL C version 1.0 does not support the 'auto' storage class specifier