Hi rsmith,
Conversion of string literals to non-const char* is deprecated in C++03, and is
ill-formed in C++11.
This patch also fixes PR16314.
http://llvm-reviews.chandlerc.com/D1965
Files:
lib/Sema/SemaOverload.cpp
test/SemaCXX/cxx0x-type-convert-construct.cpp
test/SemaCXX/deprecated.cpp
test/SemaCXX/overload-0x.cpp
unittests/ASTMatchers/ASTMatchersTest.cpp
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -1513,7 +1513,11 @@
FromType = S.Context.getArrayDecayedType(FromType);
if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) {
- // This conversion is deprecated. (C++ D.4).
+ // This conversion is ill-formed as of C++11.
+ if (S.getLangOpts().CPlusPlus11)
+ return false;
+
+ // This conversion is deprecated in C++03 (D.4)
SCS.DeprecatedStringLiteralToCharPtr = true;
// For the purpose of ranking in overload resolution
Index: test/SemaCXX/cxx0x-type-convert-construct.cpp
===================================================================
--- test/SemaCXX/cxx0x-type-convert-construct.cpp
+++ test/SemaCXX/cxx0x-type-convert-construct.cpp
@@ -9,9 +9,9 @@
Ustr = U"a UTF-32 string"; // expected-error {{assigning to 'char32_t *'
from incompatible type 'const char32_t [16]'}}
char *Rstr;
- Rstr = R"foo(a raw string)foo"; // expected-warning{{conversion from string
literal to 'char *' is deprecated}}
+ Rstr = R"foo(a raw string)foo"; // expected-error {{assigning to 'char *'
from incompatible type 'const char [13]'}}
wchar_t *LRstr;
- LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{conversion from
string literal to 'wchar_t *' is deprecated}}
+ LRstr = LR"foo(a wide raw string)foo"; // expected-error {{assigning to
'wchar_t *' from incompatible type 'const wchar_t [18]'}}
char *u8Rstr;
u8Rstr = u8R"foo(a UTF-8 raw string)foo"; // expected-error {{assigning to
'char *' from incompatible type 'const char [19]'}}
char16_t *uRstr;
Index: test/SemaCXX/deprecated.cpp
===================================================================
--- test/SemaCXX/deprecated.cpp
+++ test/SemaCXX/deprecated.cpp
@@ -28,8 +28,11 @@
bool b;
++b; // expected-warning {{incrementing expression of type bool is
deprecated}}
- // FIXME: This is ill-formed in C++11.
+#if __cplusplus < 201103L
char *p = "foo"; // expected-warning {{conversion from string literal to
'char *' is deprecated}}
+#else
+ char *p = "foo"; // expected-error {{cannot initialize a variable of type
'char *' with an lvalue of type 'const char [4]'}}
+#endif
}
struct S { int n; };
Index: test/SemaCXX/overload-0x.cpp
===================================================================
--- test/SemaCXX/overload-0x.cpp
+++ test/SemaCXX/overload-0x.cpp
@@ -9,3 +9,12 @@
a = "help"; // expected-error {{no viable overloaded '='}}
}
}
+
+namespace PR16314 {
+ void f(char*);
+ int &f(...);
+ void x()
+ {
+ int &r = f("foo");
+ }
+}
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -2583,13 +2583,15 @@
}
TEST(FunctionalCast, MatchesSimpleCase) {
+ // ill-formed in C++11
std::string foo_class = "class Foo { public: Foo(char*); };";
- EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
- functionalCastExpr()));
+ EXPECT_TRUE(matchesConditionally(foo_class +
+ "void r() { Foo f = Foo(\"hello world\");
}",
+ functionalCastExpr(), true, "-std=c++98"));
}
TEST(FunctionalCast, DoesNotMatchOtherCasts) {
- std::string FooClass = "class Foo { public: Foo(char*); };";
+ std::string FooClass = "class Foo { public: Foo(const char*); };";
EXPECT_TRUE(
notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
functionalCastExpr()));
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -1513,7 +1513,11 @@
FromType = S.Context.getArrayDecayedType(FromType);
if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) {
- // This conversion is deprecated. (C++ D.4).
+ // This conversion is ill-formed as of C++11.
+ if (S.getLangOpts().CPlusPlus11)
+ return false;
+
+ // This conversion is deprecated in C++03 (D.4)
SCS.DeprecatedStringLiteralToCharPtr = true;
// For the purpose of ranking in overload resolution
Index: test/SemaCXX/cxx0x-type-convert-construct.cpp
===================================================================
--- test/SemaCXX/cxx0x-type-convert-construct.cpp
+++ test/SemaCXX/cxx0x-type-convert-construct.cpp
@@ -9,9 +9,9 @@
Ustr = U"a UTF-32 string"; // expected-error {{assigning to 'char32_t *' from incompatible type 'const char32_t [16]'}}
char *Rstr;
- Rstr = R"foo(a raw string)foo"; // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+ Rstr = R"foo(a raw string)foo"; // expected-error {{assigning to 'char *' from incompatible type 'const char [13]'}}
wchar_t *LRstr;
- LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}}
+ LRstr = LR"foo(a wide raw string)foo"; // expected-error {{assigning to 'wchar_t *' from incompatible type 'const wchar_t [18]'}}
char *u8Rstr;
u8Rstr = u8R"foo(a UTF-8 raw string)foo"; // expected-error {{assigning to 'char *' from incompatible type 'const char [19]'}}
char16_t *uRstr;
Index: test/SemaCXX/deprecated.cpp
===================================================================
--- test/SemaCXX/deprecated.cpp
+++ test/SemaCXX/deprecated.cpp
@@ -28,8 +28,11 @@
bool b;
++b; // expected-warning {{incrementing expression of type bool is deprecated}}
- // FIXME: This is ill-formed in C++11.
+#if __cplusplus < 201103L
char *p = "foo"; // expected-warning {{conversion from string literal to 'char *' is deprecated}}
+#else
+ char *p = "foo"; // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'const char [4]'}}
+#endif
}
struct S { int n; };
Index: test/SemaCXX/overload-0x.cpp
===================================================================
--- test/SemaCXX/overload-0x.cpp
+++ test/SemaCXX/overload-0x.cpp
@@ -9,3 +9,12 @@
a = "help"; // expected-error {{no viable overloaded '='}}
}
}
+
+namespace PR16314 {
+ void f(char*);
+ int &f(...);
+ void x()
+ {
+ int &r = f("foo");
+ }
+}
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -2583,13 +2583,15 @@
}
TEST(FunctionalCast, MatchesSimpleCase) {
+ // ill-formed in C++11
std::string foo_class = "class Foo { public: Foo(char*); };";
- EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
- functionalCastExpr()));
+ EXPECT_TRUE(matchesConditionally(foo_class +
+ "void r() { Foo f = Foo(\"hello world\"); }",
+ functionalCastExpr(), true, "-std=c++98"));
}
TEST(FunctionalCast, DoesNotMatchOtherCasts) {
- std::string FooClass = "class Foo { public: Foo(char*); };";
+ std::string FooClass = "class Foo { public: Foo(const char*); };";
EXPECT_TRUE(
notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
functionalCastExpr()));
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits