diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -302,6 +302,10 @@ - ASAN_OPTIONS=detect_stack_use_after_return=1 (only on Linux). - MSAN_OPTIONS=poison_in_dtor=1. +- Some type-trait builtins, such as ``__has_trivial_assign``, have been documented + as deprecated for a while because their semantics don't mix well with post-C++11 type-traits. + Clang now emits deprecation warnings for them under the flag ``-Wdeprecated-builtins``. + New Compiler Flags ------------------ - Added the ``-fno-knr-functions`` flag to allow users to opt into the C2x diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -187,6 +187,7 @@ def : DiagGroup<"partial-availability", [UnguardedAvailability]>; def DeprecatedDynamicExceptionSpec : DiagGroup<"deprecated-dynamic-exception-spec">; +def DeprecatedBuiltins : DiagGroup<"deprecated-builtins">; def DeprecatedImplementations :DiagGroup<"deprecated-implementations">; def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">; def DeprecatedRegister : DiagGroup<"deprecated-register">; @@ -209,6 +210,7 @@ DeprecatedEnumCompareConditional, DeprecatedEnumEnumConversion, DeprecatedEnumFloatConversion, + DeprecatedBuiltins, DeprecatedIncrementBool, DeprecatedPragma, DeprecatedRegister, diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5557,6 +5557,9 @@ def warn_unavailable_def : Warning< "implementing unavailable method">, InGroup, DefaultIgnore; +def warn_deprecated_builtin : Warning< + "builtin %0 is deprecated; use %1 instead">, + InGroup; def err_unavailable : Error<"%0 is unavailable">; def err_property_method_unavailable : Error<"property access is using %0 method which is unavailable">; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -5394,6 +5394,39 @@ return false; } +namespace { +void DiagnoseBuiltinDeprecation(Sema& S, TypeTrait Kind, + SourceLocation KWLoc) { + TypeTrait Replacement; + switch (Kind) { + case UTT_HasNothrowAssign: + case UTT_HasNothrowMoveAssign: + Replacement = BTT_IsNothrowAssignable; + break; + case UTT_HasNothrowCopy: + case UTT_HasNothrowConstructor: + Replacement = TT_IsNothrowConstructible; + break; + case UTT_HasTrivialAssign: + case UTT_HasTrivialMoveAssign: + Replacement = BTT_IsTriviallyAssignable; + break; + case UTT_HasTrivialCopy: + case UTT_HasTrivialDefaultConstructor: + case UTT_HasTrivialMoveConstructor: + Replacement = TT_IsTriviallyConstructible; + break; + case UTT_HasTrivialDestructor: + Replacement = UTT_IsTriviallyDestructible; + break; + default: + return; + } + S.Diag(KWLoc, diag::warn_deprecated_builtin) + << getTraitSpelling(Kind) << getTraitSpelling(Replacement); +} +} + ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef Args, SourceLocation RParenLoc) { @@ -5403,6 +5436,8 @@ *this, Kind, KWLoc, Args[0]->getType())) return ExprError(); + DiagnoseBuiltinDeprecation(*this, Kind, KWLoc); + bool Dependent = false; for (unsigned I = 0, N = Args.size(); I != N; ++I) { if (Args[I]->getType()->isDependentType()) { diff --git a/clang/test/CXX/dcl.decl/dcl.init/p5.cpp b/clang/test/CXX/dcl.decl/dcl.init/p5.cpp --- a/clang/test/CXX/dcl.decl/dcl.init/p5.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/p5.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-deprecated-builtins -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-deprecated-builtins -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-deprecated-builtins %s // A program that calls for default-initialization or value-initialization of // an entity of reference type is illformed. If T is a cv-qualified type, the diff --git a/clang/test/CXX/drs/dr18xx.cpp b/clang/test/CXX/drs/dr18xx.cpp --- a/clang/test/CXX/drs/dr18xx.cpp +++ b/clang/test/CXX/drs/dr18xx.cpp @@ -1,8 +1,8 @@ -// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++2a -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++2a -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors #if __cplusplus < 201103L // expected-error@+1 {{variadic macro}} diff --git a/clang/test/CXX/drs/dr21xx.cpp b/clang/test/CXX/drs/dr21xx.cpp --- a/clang/test/CXX/drs/dr21xx.cpp +++ b/clang/test/CXX/drs/dr21xx.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors #if __cplusplus < 201103L // expected-error@+1 {{variadic macro}} diff --git a/clang/test/CXX/special/class.copy/p12-0x.cpp b/clang/test/CXX/special/class.copy/p12-0x.cpp --- a/clang/test/CXX/special/class.copy/p12-0x.cpp +++ b/clang/test/CXX/special/class.copy/p12-0x.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-defaulted-function-deleted -// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-defaulted-function-deleted -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14 +// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins -Wno-defaulted-function-deleted +// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins -Wno-defaulted-function-deleted -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14 // expected-no-diagnostics diff --git a/clang/test/CXX/special/class.copy/p25-0x.cpp b/clang/test/CXX/special/class.copy/p25-0x.cpp --- a/clang/test/CXX/special/class.copy/p25-0x.cpp +++ b/clang/test/CXX/special/class.copy/p25-0x.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c++11 -verify %s -// RUN: %clang_cc1 -std=c++11 -verify %s -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14 +// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins +// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14 // expected-no-diagnostics diff --git a/clang/test/CXX/special/class.ctor/p5-0x.cpp b/clang/test/CXX/special/class.ctor/p5-0x.cpp --- a/clang/test/CXX/special/class.ctor/p5-0x.cpp +++ b/clang/test/CXX/special/class.ctor/p5-0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-defaulted-function-deleted +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-deprecated-builtins -Wno-defaulted-function-deleted struct DefaultedDefCtor1 {}; struct DefaultedDefCtor2 { DefaultedDefCtor2() = default; }; diff --git a/clang/test/Modules/cxx-decls.cpp b/clang/test/Modules/cxx-decls.cpp --- a/clang/test/Modules/cxx-decls.cpp +++ b/clang/test/Modules/cxx-decls.cpp @@ -1,6 +1,6 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 -// RUN: %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -ast-dump -ast-dump-filter merge -std=c++11 | FileCheck %s +// RUN: %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Wno-deprecated-builtins -I %S/Inputs %s -verify -std=c++11 +// RUN: %clang_cc1 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Wno-deprecated-builtins -I %S/Inputs %s -ast-dump -ast-dump-filter merge -std=c++11 | FileCheck %s // expected-no-diagnostics diff --git a/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp b/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp --- a/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp +++ b/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fcxx-exceptions %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fcxx-exceptions -Wno-deprecated-builtins %s void fn() = default; // expected-error {{only special member}} struct foo { diff --git a/clang/test/SemaCXX/cxx11-crashes.cpp b/clang/test/SemaCXX/cxx11-crashes.cpp --- a/clang/test/SemaCXX/cxx11-crashes.cpp +++ b/clang/test/SemaCXX/cxx11-crashes.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -verify %s +// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins // rdar://12240916 stack overflow. namespace rdar12240916 { diff --git a/clang/test/SemaCXX/deprecated-builtins.cpp b/clang/test/SemaCXX/deprecated-builtins.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/deprecated-builtins.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A {}; + +void f() { + bool a; + + a = __has_nothrow_assign(A); // expected-warning-re {{__has_nothrow_assign {{.*}} use __is_nothrow_assignable}} + a = __has_nothrow_move_assign(A); // expected-warning-re {{__has_nothrow_move_assign {{.*}} use __is_nothrow_assignable}} + a = __has_nothrow_copy(A); // expected-warning-re {{__has_nothrow_copy {{.*}} use __is_nothrow_constructible}} + a = __has_nothrow_constructor(A); // expected-warning-re {{__has_nothrow_constructor {{.*}} use __is_nothrow_constructible}} + a = __has_trivial_assign(A); // expected-warning-re {{__has_trivial_assign {{.*}} use __is_trivially_assignable}} + a = __has_trivial_move_assign(A); // expected-warning-re {{__has_trivial_move_assign {{.*}} use __is_trivially_assignable}} + a = __has_trivial_copy(A); // expected-warning-re {{__has_trivial_copy {{.*}} use __is_trivially_constructible}} + a = __has_trivial_constructor(A); // expected-warning-re {{__has_trivial_constructor {{.*}} use __is_trivially_constructible}} + a = __has_trivial_move_constructor(A); // expected-warning-re {{__has_trivial_move_constructor {{.*}} use __is_trivially_constructible}} + a = __has_trivial_destructor(A); // expected-warning-re {{__has_trivial_destructor {{.*}} use __is_trivially_destructible}} + +} diff --git a/clang/test/SemaCXX/sizeless-1.cpp b/clang/test/SemaCXX/sizeless-1.cpp --- a/clang/test/SemaCXX/sizeless-1.cpp +++ b/clang/test/SemaCXX/sizeless-1.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++98 %s -// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++11 %s -// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++17 %s -// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=gnu++17 %s +// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-deprecated-builtins -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++98 %s +// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-deprecated-builtins -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++11 %s +// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-deprecated-builtins -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++17 %s +// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-deprecated-builtins -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=gnu++17 %s namespace std { struct type_info; diff --git a/clang/test/SemaCXX/trivial-constructor.cpp b/clang/test/SemaCXX/trivial-constructor.cpp --- a/clang/test/SemaCXX/trivial-constructor.cpp +++ b/clang/test/SemaCXX/trivial-constructor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-deprecated-builtins // expected-no-diagnostics struct T1 { }; diff --git a/clang/test/SemaCXX/trivial-destructor.cpp b/clang/test/SemaCXX/trivial-destructor.cpp --- a/clang/test/SemaCXX/trivial-destructor.cpp +++ b/clang/test/SemaCXX/trivial-destructor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-deprecated-builtins // expected-no-diagnostics struct T1 { }; diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fms-extensions -Wno-microsoft %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -fms-extensions -Wno-microsoft %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -fms-extensions -Wno-microsoft %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s #define T(b) (b) ? 1 : -1 #define F(b) (b) ? -1 : 1 diff --git a/clang/test/SemaObjCXX/arc-type-traits.mm b/clang/test/SemaObjCXX/arc-type-traits.mm --- a/clang/test/SemaObjCXX/arc-type-traits.mm +++ b/clang/test/SemaObjCXX/arc-type-traits.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -std=c++11 %s -Wno-deprecated-builtins // expected-no-diagnostics // Check the results of the various type-trait query functions on diff --git a/clang/test/SemaObjCXX/objc-weak-type-traits.mm b/clang/test/SemaObjCXX/objc-weak-type-traits.mm --- a/clang/test/SemaObjCXX/objc-weak-type-traits.mm +++ b/clang/test/SemaObjCXX/objc-weak-type-traits.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s -Wno-deprecated-builtins // expected-no-diagnostics // Check the results of the various type-trait query functions on