From: Richard Smith Date: Fri, 24 Feb 2012 18:10:23 +0000 (+0000) Subject: __decltype is a GNU extension, not a C++11 extension. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=39304fad1c8a7b7e64121e9ae544b18e460b682c;p=clang __decltype is a GNU extension, not a C++11 extension. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151377 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 3fd7e90083..b3f2067ff6 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -254,6 +254,12 @@ def err_missing_comma_before_ellipsis : Error< "C requires a comma prior to the ellipsis in a variadic function type">; def err_unexpected_typedef_ident : Error< "unexpected type name %0: expected identifier">; +def ext_gnu_decltype : Extension< + "'__decltype' type specifier is a GNU extension">, + InGroup, DefaultIgnore; +def warn_cxx98_compat_decltype : Warning< + "'decltype' type specifier is incompatible with C++98">, + InGroup, DefaultIgnore; def err_unexpected_scope_on_base_decltype : Error< "unexpected namespace scope prior to decltype">; def err_expected_class_name : Error<"expected class name">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index bfece366f1..b961e0961a 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1176,9 +1176,6 @@ def warn_cxx98_compat_temp_copy : Warning< InGroup, DefaultIgnore; // C++11 decltype -def warn_cxx98_compat_decltype : Warning< - "'decltype' type specifier is incompatible with C++98">, - InGroup, DefaultIgnore; def err_decltype_in_declarator : Error< "'decltype' cannot be used to name a declaration">; diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index c2bf54db2c..5468700bc9 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -653,6 +653,9 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { return EndLoc; } } else { + Diag(Tok, Tok.getIdentifierInfo()->isStr("decltype") + ? diag::warn_cxx98_compat_decltype : diag::ext_gnu_decltype); + ConsumeToken(); BalancedDelimiterTracker T(*this, tok::l_paren); diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index 11818f6fa2..72a51bc474 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -898,8 +898,6 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32) Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type) << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t"); - if (TypeSpecType == TST_decltype) - Diag(D, TSTLoc, diag::warn_cxx98_compat_decltype); if (Constexpr_specified) Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr); diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp index b7abe266f2..879c72211d 100644 --- a/test/SemaCXX/cxx98-compat.cpp +++ b/test/SemaCXX/cxx98-compat.cpp @@ -99,6 +99,7 @@ char16_t c16 = 0; // expected-warning {{'char16_t' type specifier is incompatibl char32_t c32 = 0; // expected-warning {{'char32_t' type specifier is incompatible with C++98}} constexpr int const_expr = 0; // expected-warning {{'constexpr' specifier is incompatible with C++98}} decltype(const_expr) decl_type = 0; // expected-warning {{'decltype' type specifier is incompatible with C++98}} +__decltype(const_expr) decl_type2 = 0; // ok void no_except() noexcept; // expected-warning {{noexcept specifications are incompatible with C++98}} bool no_except_expr = noexcept(1 + 1); // expected-warning {{noexcept expressions are incompatible with C++98}} void *null = nullptr; // expected-warning {{'nullptr' is incompatible with C++98}} diff --git a/test/SemaCXX/decltype-98.cpp b/test/SemaCXX/decltype-98.cpp index db52565e6c..44d5896c53 100644 --- a/test/SemaCXX/decltype-98.cpp +++ b/test/SemaCXX/decltype-98.cpp @@ -1,3 +1,3 @@ -// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s -Wgnu extern int x; -__decltype(1) x = 3; +__decltype(1) x = 3; // expected-warning {{is a GNU extension}}