t.p.northover created this revision. Herald added a subscriber: mcrosier. Hi all,
So, I've finally managed to run all the tests I wanted and get this out for review. Sorry it's taken so long. This patch switches Clang's default C++ target to C++14 across all platforms and updates the test-suite to pass. I've managed to test Linux, macOS and iOS on both the regression tests and the test-suite (minus externals on Linux because it's my home machine). There's a separate patch for the test-suite which I'll attach to a follow-up message here. I think most of the test changes are pretty straightforward and fall into a few broad categories: - Changes to how the operands for "operator new" are promoted and otherwise wrangled in C++14. Slightly different CodeGen but essentially fine. - Some tests explicitly testing C++ mode differences left the C++98 line without a -std=... argument, I added it. - OpenMP CodeGen changes. As far as I can tell both are correct, but the tests are essentially unreadable so I gave up trying to adapt the output and just set it to C++98 mode. I'm happy to rework anything people think needs changing. Repository: rC Clang https://reviews.llvm.org/D40948 Files: clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGenCXX/new-overflow.cpp clang/test/CodeGenCXX/new.cpp clang/test/CodeGenCXX/vtable-available-externally.cpp clang/test/Lexer/cxx-features.cpp clang/test/Lexer/half-literal.cpp clang/test/OpenMP/taskloop_reduction_codegen.cpp clang/test/OpenMP/taskloop_simd_reduction_codegen.cpp clang/test/Parser/cxx1z-nested-namespace-definition.cpp clang/test/SemaCXX/new-array-size-conv.cpp clang/test/SemaCXX/new-delete.cpp clang/test/SemaCXX/unknown-type-name.cpp clang/test/SemaTemplate/class-template-decl.cpp clang/test/SemaTemplate/explicit-instantiation.cpp
Index: clang/test/SemaTemplate/explicit-instantiation.cpp =================================================================== --- clang/test/SemaTemplate/explicit-instantiation.cpp +++ clang/test/SemaTemplate/explicit-instantiation.cpp @@ -124,10 +124,10 @@ namespace undefined_static_data_member { template<typename T> struct A { static int a; // expected-note {{here}} - template<typename U> static int b; // expected-note {{here}} expected-warning {{extension}} + template<typename U> static int b; // expected-note {{here}} expected-warning 0+ {{extension}} }; struct B { - template<typename U> static int c; // expected-note {{here}} expected-warning {{extension}} + template<typename U> static int c; // expected-note {{here}} expected-warning 0+ {{extension}} }; template int A<int>::a; // expected-error {{explicit instantiation of undefined static data member 'a' of class template 'undefined_static_data_member::A<int>'}} @@ -137,14 +137,14 @@ template<typename T> struct C { static int a; - template<typename U> static int b; // expected-warning {{extension}} + template<typename U> static int b; // expected-warning 0+ {{extension}} }; struct D { - template<typename U> static int c; // expected-warning {{extension}} + template<typename U> static int c; // expected-warning 0+ {{extension}} }; template<typename T> int C<T>::a; - template<typename T> template<typename U> int C<T>::b; // expected-warning {{extension}} - template<typename U> int D::c; // expected-warning {{extension}} + template<typename T> template<typename U> int C<T>::b; // expected-warning 0+ {{extension}} + template<typename U> int D::c; // expected-warning 0+ {{extension}} template int C<int>::a; template int C<int>::b<int>; Index: clang/test/SemaTemplate/class-template-decl.cpp =================================================================== --- clang/test/SemaTemplate/class-template-decl.cpp +++ clang/test/SemaTemplate/class-template-decl.cpp @@ -57,8 +57,7 @@ template<typename T> class X; // expected-error{{expression}} } -template<typename T> class X1 var; // expected-warning{{variable templates are a C++14 extension}} \ - // expected-error {{variable has incomplete type 'class X1'}} \ +template<typename T> class X1 var; // expected-error {{variable has incomplete type 'class X1'}} \ // expected-note {{forward declaration of 'X1'}} namespace M { Index: clang/test/SemaCXX/unknown-type-name.cpp =================================================================== --- clang/test/SemaCXX/unknown-type-name.cpp +++ clang/test/SemaCXX/unknown-type-name.cpp @@ -95,7 +95,10 @@ template<typename T> int h(T::type, int); // expected-error{{missing 'typename'}} template<typename T> int h(T::type x, char); // expected-error{{missing 'typename'}} -template<typename T> int junk1(T::junk); // expected-warning{{variable templates are a C++14 extension}} +template<typename T> int junk1(T::junk); +#if __cplusplus <= 201103L +// expected-warning@-2 {{variable templates are a C++14 extension}} +#endif template<typename T> int junk2(T::junk) throw(); // expected-error{{missing 'typename'}} template<typename T> int junk3(T::junk) = delete; // expected-error{{missing 'typename'}} #if __cplusplus <= 199711L @@ -106,7 +109,11 @@ // FIXME: We can tell this was intended to be a function because it does not // have a dependent nested name specifier. -template<typename T> int i(T::type, int()); // expected-warning{{variable templates are a C++14 extension}} +template<typename T> int i(T::type, int()); +#if __cplusplus <= 201103L +// expected-warning@-2 {{variable templates are a C++14 extension}} +#endif + // FIXME: We know which type specifier should have been specified here. Provide // a fix-it to add 'typename A<T>::type' Index: clang/test/SemaCXX/new-delete.cpp =================================================================== --- clang/test/SemaCXX/new-delete.cpp +++ clang/test/SemaCXX/new-delete.cpp @@ -80,27 +80,43 @@ (void)new int[1.1]; #if __cplusplus <= 199711L // expected-error@-2 {{array size expression must have integral or enumeration type, not 'double'}} -#else +#elif __cplusplus <= 201103L // expected-error@-4 {{array size expression must have integral or unscoped enumeration type, not 'double'}} +#else + // expected-warning@-6 {{implicit conversion from 'double' to 'unsigned int' changes value from 1.1 to 1}} #endif - (void)new int[1][i]; // expected-error {{only the first dimension}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} - (void)new (int[1][i]); // expected-error {{only the first dimension}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} + (void)new int[1][i]; // expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} + (void)new (int[1][i]); // expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} +#if __cplusplus <= 201103L + // expected-error@-3 {{only the first dimension}} + // expected-error@-3 {{only the first dimension}} +#else + // expected-error@-6 {{array size is not a constant expression}} + // expected-error@-6 {{array size is not a constant expression}} +#endif (void)new (int[i]); // expected-warning {{when type is in parentheses}} (void)new int(*(S*)0); // expected-error {{no viable conversion from 'S' to 'int'}} (void)new int(1, 2); // expected-error {{excess elements in scalar initializer}} (void)new S(1); // expected-error {{no matching constructor}} (void)new S(1, 1); // expected-error {{call to constructor of 'S' is ambiguous}} (void)new const int; // expected-error {{default initialization of an object of const type 'const int'}} (void)new float*(ip); // expected-error {{cannot initialize a new value of type 'float *' with an lvalue of type 'int *'}} // Undefined, but clang should reject it directly. - (void)new int[-1]; // expected-error {{array size is negative}} + (void)new int[-1]; +#if __cplusplus <= 201103L + // expected-error@-2 {{array size is negative}} +#else + // expected-error@-4 {{array is too large}} +#endif (void)new int[2000000000]; // expected-error {{array is too large}} (void)new int[*(S*)0]; #if __cplusplus <= 199711L // expected-error@-2 {{array size expression must have integral or enumeration type, not 'S'}} -#else +#elif __cplusplus <= 201103L // expected-error@-4 {{array size expression must have integral or unscoped enumeration type, not 'S'}} +#else + // expected-error@-6 {{converting 'S' to incompatible type}} #endif (void)::S::new int; // expected-error {{expected unqualified-id}} Index: clang/test/SemaCXX/new-array-size-conv.cpp =================================================================== --- clang/test/SemaCXX/new-array-size-conv.cpp +++ clang/test/SemaCXX/new-array-size-conv.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=gnu++98 %s // RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++98 %s // RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++11 %s Index: clang/test/Parser/cxx1z-nested-namespace-definition.cpp =================================================================== --- clang/test/Parser/cxx1z-nested-namespace-definition.cpp +++ clang/test/Parser/cxx1z-nested-namespace-definition.cpp @@ -1,5 +1,5 @@ // RUN: cp %s %t -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 // RUN: not %clang_cc1 -x c++ -fixit %t -Werror -DFIXIT // RUN: %clang_cc1 -x c++ %t -DFIXIT // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++17 -Wc++14-compat Index: clang/test/OpenMP/taskloop_simd_reduction_codegen.cpp =================================================================== --- clang/test/OpenMP/taskloop_simd_reduction_codegen.cpp +++ clang/test/OpenMP/taskloop_simd_reduction_codegen.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - -triple powerpc64le-unknown-linux-gnu | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - -triple powerpc64le-unknown-linux-gnu -std=c++98 | FileCheck %s // expected-no-diagnostics struct S { Index: clang/test/OpenMP/taskloop_reduction_codegen.cpp =================================================================== --- clang/test/OpenMP/taskloop_reduction_codegen.cpp +++ clang/test/OpenMP/taskloop_reduction_codegen.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - -triple powerpc64le-unknown-linux-gnu | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - -triple powerpc64le-unknown-linux-gnu -std=c++98 | FileCheck %s // expected-no-diagnostics struct S { Index: clang/test/Lexer/half-literal.cpp =================================================================== --- clang/test/Lexer/half-literal.cpp +++ clang/test/Lexer/half-literal.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s -float a = 1.0h; // expected-error{{invalid suffix 'h' on floating constant}} +float a = 1.0h; // expected-error{{no matching literal operator for call to 'operator""h' with argument of type 'long double' or 'const char *', and no matching literal operator template}} float b = 1.0H; // expected-error{{invalid suffix 'H' on floating constant}} _Float16 c = 1.f166; // expected-error{{invalid suffix 'f166' on floating constant}} Index: clang/test/Lexer/cxx-features.cpp =================================================================== --- clang/test/Lexer/cxx-features.cpp +++ clang/test/Lexer/cxx-features.cpp @@ -4,8 +4,8 @@ // RUN: %clang_cc1 -std=c++14 -fcxx-exceptions -fsized-deallocation -verify %s // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fsized-deallocation -verify %s // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fsized-deallocation -fconcepts-ts -DCONCEPTS_TS=1 -verify %s -// RUN: %clang_cc1 -fno-rtti -fno-threadsafe-statics -verify %s -DNO_EXCEPTIONS -DNO_RTTI -DNO_THREADSAFE_STATICS -// RUN: %clang_cc1 -fcoroutines-ts -DNO_EXCEPTIONS -DCOROUTINES -verify %s +// RUN: %clang_cc1 -fno-rtti -fno-threadsafe-statics -verify %s -DNO_EXCEPTIONS -DNO_RTTI -DNO_THREADSAFE_STATICS -fsized-deallocation +// RUN: %clang_cc1 -fcoroutines-ts -DNO_EXCEPTIONS -DCOROUTINES -verify -fsized-deallocation %s // expected-no-diagnostics Index: clang/test/CodeGenCXX/vtable-available-externally.cpp =================================================================== --- clang/test/CodeGenCXX/vtable-available-externally.cpp +++ clang/test/CodeGenCXX/vtable-available-externally.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o %t -// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -O2 -disable-llvm-passes -emit-llvm -o %t.opt +// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t +// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt // RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t // RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t // RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t Index: clang/test/CodeGenCXX/new.cpp =================================================================== --- clang/test/CodeGenCXX/new.cpp +++ clang/test/CodeGenCXX/new.cpp @@ -255,8 +255,6 @@ // CHECK-LABEL: define void @_ZN6test155test2EPvi( // CHECK: [[N:%.*]] = load i32, i32* // CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64 - // CHECK-NEXT: [[T1:%.*]] = icmp slt i64 [[T0]], 0 - // CHECK-NEXT: [[T2:%.*]] = select i1 [[T1]], i64 -1, i64 [[T0]] // CHECK-NEXT: [[P:%.*]] = load i8*, i8** // CHECK: [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]* // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq i64 [[T0]], 0 Index: clang/test/CodeGenCXX/new-overflow.cpp =================================================================== --- clang/test/CodeGenCXX/new-overflow.cpp +++ clang/test/CodeGenCXX/new-overflow.cpp @@ -85,9 +85,7 @@ // CHECK: define [[A:%.*]]* @_ZN5test44testEs(i16 signext // CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32 - // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0 - // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]] - // CHECK-NEXT: call i8* @_Znaj(i32 [[T1]]) + // CHECK-NEXT: call i8* @_Znaj(i32 [[N]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[N]] elt *test(short s) { return new elt[s]; @@ -104,9 +102,7 @@ // CHECK: define [[A:%.*]]* @_ZN5test54testEi(i32 // CHECK: [[N:%.*]] = load i32, i32* - // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0 - // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]] - // CHECK-NEXT: call i8* @_Znaj(i32 [[T1]]) + // CHECK-NEXT: call i8* @_Znaj(i32 [[N]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[N]] elt *test(int s) { return new elt[s]; @@ -169,13 +165,11 @@ // CHECK: define [[A:%.*]]* @_ZN5test84testEx(i64 // CHECK: [[N:%.*]] = load i64, i64* - // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296 // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32 // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4) // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1 - // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]] // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0 - // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]] + // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]] // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[T1]] elt *test(long long s) { @@ -194,13 +188,11 @@ // CHECK: define [[A:%.*]]* @_ZN5test94testEy(i64 // CHECK: [[N:%.*]] = load i64, i64* - // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296 // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32 // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4) // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1 - // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]] // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0 - // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]] + // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]] // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]]) // CHECK: getelementptr inbounds {{.*}}, i32 [[T1]] elt *test(unsigned long long s) { Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -1730,10 +1730,7 @@ case InputKind::CXX: case InputKind::ObjCXX: // The PS4 uses C++11 as the default C++ standard. - if (T.isPS4()) - LangStd = LangStandard::lang_gnucxx11; - else - LangStd = LangStandard::lang_gnucxx98; + LangStd = LangStandard::lang_gnucxx14; break; case InputKind::RenderScript: LangStd = LangStandard::lang_c99;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits