[cfe-dev] Setting default dialect to C++11
Tim Northover via cfe-dev
cfe-dev at lists.llvm.org
Thu Aug 24 15:18:44 PDT 2017
Hi Paul,
On 24 August 2017 at 14:10, Robinson, Paul via cfe-dev
<cfe-dev at lists.llvm.org> wrote:
> It's clearly too late to make a change like this for 5.0. Is there any
> remaining roadblock to making the change for 6.0 (trunk)?
I've been slowly trying to make Clang C++14 clean. I think most of the
actual changes needed for Clang are in place now (the big one was
making C++14 mode friendlier to imaginary constants) and the rest is
fixing up tests.
I think most of the test changes are because the wording on how the
arguments to "operator new" get treated (promotion etc) was changed.
I've attached a WiP diff here for reference. Unfortunately it's not
even complete and these 4 tests still fail:
Clang :: CodeGenCXX/vtable-available-externally.cpp
Clang :: Lexer/cxx-features.cpp
Clang :: OpenMP/taskloop_reduction_codegen.cpp
Clang :: OpenMP/taskloop_simd_reduction_codegen.cpp
I don't even think they're particularly difficult ones, just where I
happened to stop when I last looked at it. I've also got to address
some review comments from Richard (I haven't forgotten) to make sure
we haven't decreased C-mode OpenMP coverage.
There are also a handful of bits of the test-suite that need to
explicitly specify c++98.
So I think the actual work needed is pretty small (and I can find time
to do it, probably even this weekend or something). We just need to
make the decision: C++11 or C++14 and go or no-go. My vote is go and
C++14.
Cheers.
Tim.
-------------- next part --------------
commit 8d199edd8501cdc16c1b6861046cf75b89d62060
Author: Tim Northover <t.p.northover at gmail.com>
Date: Fri May 19 06:58:58 2017 -0700
TMP: switch to C++14
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 24a08e84dc4..575556869fd 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1667,10 +1667,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
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;
diff --git a/clang/test/CodeGenCXX/new-overflow.cpp b/clang/test/CodeGenCXX/new-overflow.cpp
index 0c4c3c823d1..b27984f66ab 100644
--- a/clang/test/CodeGenCXX/new-overflow.cpp
+++ b/clang/test/CodeGenCXX/new-overflow.cpp
@@ -85,9 +85,7 @@ namespace test4 {
// 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 @@ namespace test5 {
// 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 @@ namespace test8 {
// 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 @@ namespace test9 {
// 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) {
diff --git a/clang/test/CodeGenCXX/new.cpp b/clang/test/CodeGenCXX/new.cpp
index ae2ec1505c5..3bebc2ab8ac 100644
--- a/clang/test/CodeGenCXX/new.cpp
+++ b/clang/test/CodeGenCXX/new.cpp
@@ -255,8 +255,6 @@ namespace test15 {
// 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
diff --git a/clang/test/Lexer/half-literal.cpp b/clang/test/Lexer/half-literal.cpp
index 32af3faef9a..0dcbe95632e 100644
--- a/clang/test/Lexer/half-literal.cpp
+++ b/clang/test/Lexer/half-literal.cpp
@@ -1,3 +1,3 @@
// 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}}
diff --git a/clang/test/Parser/cxx1z-nested-namespace-definition.cpp b/clang/test/Parser/cxx1z-nested-namespace-definition.cpp
index e5e809aa036..e0c5244a373 100644
--- a/clang/test/Parser/cxx1z-nested-namespace-definition.cpp
+++ b/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
diff --git a/clang/test/SemaCXX/new-array-size-conv.cpp b/clang/test/SemaCXX/new-array-size-conv.cpp
index dbdd4bd8951..36b2f23a0e9 100644
--- a/clang/test/SemaCXX/new-array-size-conv.cpp
+++ b/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
diff --git a/clang/test/SemaCXX/new-delete.cpp b/clang/test/SemaCXX/new-delete.cpp
index cb0d030d99c..870a5921d25 100644
--- a/clang/test/SemaCXX/new-delete.cpp
+++ b/clang/test/SemaCXX/new-delete.cpp
@@ -80,12 +80,21 @@ void bad_news(int *ip)
(void)new int[1.1];
#if __cplusplus <= 199711L
// expected-error at -2 {{array size expression must have integral or enumeration type, not 'double'}}
-#else
+#elif __cplusplus <= 201103L
// expected-error at -4 {{array size expression must have integral or unscoped enumeration type, not 'double'}}
+#else
+ // expected-warning at -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 at -3 {{only the first dimension}}
+ // expected-error at -3 {{only the first dimension}}
+#else
+ // expected-error at -6 {{array size is not a constant expression}}
+ // expected-error at -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}}
@@ -94,13 +103,20 @@ void bad_news(int *ip)
(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 at -2 {{array size is negative}}
+#else
+ // expected-error at -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 at -2 {{array size expression must have integral or enumeration type, not 'S'}}
-#else
+#elif __cplusplus <= 201103L
// expected-error at -4 {{array size expression must have integral or unscoped enumeration type, not 'S'}}
+#else
+ // expected-error at -6 {{converting 'S' to incompatible type}}
#endif
(void)::S::new int; // expected-error {{expected unqualified-id}}
diff --git a/clang/test/SemaCXX/unknown-type-name.cpp b/clang/test/SemaCXX/unknown-type-name.cpp
index 2a9748e3ab6..9086c9acc43 100644
--- a/clang/test/SemaCXX/unknown-type-name.cpp
+++ b/clang/test/SemaCXX/unknown-type-name.cpp
@@ -95,7 +95,10 @@ template<typename T> int A<T>::h(T::type x, char) {} // expected-error{{missing
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 at -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 @@ template<typename T> int junk4(T::junk j); // expected-error{{missing 'typename'
// 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 at -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'
diff --git a/clang/test/SemaTemplate/class-template-decl.cpp b/clang/test/SemaTemplate/class-template-decl.cpp
index 2e36cae14f6..c49154c6527 100644
--- a/clang/test/SemaTemplate/class-template-decl.cpp
+++ b/clang/test/SemaTemplate/class-template-decl.cpp
@@ -57,8 +57,7 @@ void f() {
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 {
diff --git a/clang/test/SemaTemplate/explicit-instantiation.cpp b/clang/test/SemaTemplate/explicit-instantiation.cpp
index 42d9f4d332a..d88c50bc29d 100644
--- a/clang/test/SemaTemplate/explicit-instantiation.cpp
+++ b/clang/test/SemaTemplate/explicit-instantiation.cpp
@@ -124,10 +124,10 @@ namespace PR10086 {
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 @@ namespace undefined_static_data_member {
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>;
More information about the cfe-dev
mailing list