[cfe-commits] r56137 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/Type.cpp lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp test/SemaCXX/type-convert-construct.cpp

Douglas Gregor doug.gregor at gmail.com
Thu Sep 11 17:47:35 PDT 2008


Author: dgregor
Date: Thu Sep 11 19:47:35 2008
New Revision: 56137

URL: http://llvm.org/viewvc/llvm-project?rev=56137&view=rev
Log:
Give string literals const element typesin C++, and cope with the deprecated C++ conversion from a string literal to a pointer-to-non-const-character

Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/SemaCXX/type-convert-construct.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=56137&r1=56136&r2=56137&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Sep 11 19:47:35 2008
@@ -302,6 +302,7 @@
   bool isEnumeralType() const;
   bool isBooleanType() const;
   bool isCharType() const;
+  bool isWideCharType() const;
   bool isIntegralType() const;
   
   /// Floating point categories.

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=56137&r1=56136&r2=56137&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Sep 11 19:47:35 2008
@@ -498,6 +498,14 @@
   return false;
 }
 
+bool Type::isWideCharType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() == BuiltinType::WChar;
+  if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
+    return ASQT->getBaseType()->isWideCharType();
+  return false;
+}
+
 /// isSignedIntegerType - Return true if this is an integer type that is
 /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
 /// an enum decl which has a signed representation, or a vector of signed

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=56137&r1=56136&r2=56137&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Sep 11 19:47:35 2008
@@ -890,6 +890,8 @@
   // blcok pointer types.
   AssignConvertType CheckBlockPointerTypesForAssignment(QualType lhsType, 
                                                         QualType rhsType);
+
+  bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
   
   /// the following "Check" methods will return a valid/converted QualType
   /// or a null QualType (indicating an error diagnostic was issued).

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=56137&r1=56136&r2=56137&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Sep 11 19:47:35 2008
@@ -290,6 +290,10 @@
   QualType StrTy = Context.CharTy;
   if (Literal.AnyWide) StrTy = Context.getWCharType();
   if (Literal.Pascal) StrTy = Context.UnsignedCharTy;
+
+  // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
+  if (getLangOptions().CPlusPlus)
+    StrTy.addConst();
   
   // Get an array type for the string, according to C99 6.4.5.  This includes
   // the nul terminator character as well as the string length for pascal
@@ -3066,6 +3070,18 @@
     DiagKind = diag::ext_typecheck_convert_pointer_void_func;
     break;
   case CompatiblePointerDiscardsQualifiers:
+    // If the qualifiers lost were because we were applying the
+    // (deprecated) C++ conversion from a string literal to a char*
+    // (or wchar_t*), then there was no error (C++ 4.2p2).  FIXME:
+    // Ideally, this check would be performed in
+    // CheckPointerTypesForAssignment. However, that would require a
+    // bit of refactoring (so that the second argument is an
+    // expression, rather than a type), which should be done as part
+    // of a larger effort to fix CheckPointerTypesForAssignment for
+    // C++ semantics.
+    if (getLangOptions().CPlusPlus &&
+        IsStringLiteralToNonConstPointerConversion(SrcExpr, DstType))
+      return false;
     DiagKind = diag::ext_typecheck_convert_discards_qualifiers;
     break;
   case IntToBlockPointer:

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=56137&r1=56136&r2=56137&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Sep 11 19:47:35 2008
@@ -202,3 +202,34 @@
                 Ty.getAsString(), CondExpr->getSourceRange());
   return false;
 }
+
+/// Helper function to determine whether this is the (deprecated) C++
+/// conversion from a string literal to a pointer to non-const char or
+/// non-const wchar_t (for narrow and wide string literals,
+/// respectively).
+bool 
+Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) {
+  // Look inside the implicit cast, if it exists.
+  if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(From))
+    From = Cast->getSubExpr();
+
+  // A string literal (2.13.4) that is not a wide string literal can
+  // be converted to an rvalue of type "pointer to char"; a wide
+  // string literal can be converted to an rvalue of type "pointer
+  // to wchar_t" (C++ 4.2p2).
+  if (StringLiteral *StrLit = dyn_cast<StringLiteral>(From))
+    if (const PointerType *ToPtrType = ToType->getAsPointerType())
+      if (const BuiltinType *ToPointeeType 
+          = ToPtrType->getPointeeType()->getAsBuiltinType()) {
+        // This conversion is considered only when there is an
+        // explicit appropriate pointer target type (C++ 4.2p2).
+        if (ToPtrType->getPointeeType().getCVRQualifiers() == 0 &&
+            ((StrLit->isWide() && ToPointeeType->isWideCharType()) ||
+             (!StrLit->isWide() &&
+              (ToPointeeType->getKind() == BuiltinType::Char_U ||
+               ToPointeeType->getKind() == BuiltinType::Char_S))))
+          return true;
+      }
+
+  return false;
+}

Modified: cfe/trunk/test/SemaCXX/type-convert-construct.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/type-convert-construct.cpp?rev=56137&r1=56136&r2=56137&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/type-convert-construct.cpp (original)
+++ cfe/trunk/test/SemaCXX/type-convert-construct.cpp Thu Sep 11 19:47:35 2008
@@ -10,4 +10,8 @@
   typedef int T;
   int *p;
   bool v6 = T(0) == p;
+  char *str;
+  str = "a string";
+  wchar_t *wstr;
+  wstr = L"a wide string";
 }





More information about the cfe-commits mailing list