]> granicus.if.org Git - clang/commitdiff
Don't rely on a StringRef being null-terminated (it's not) for deprecation messages.
authorBenjamin Kramer <benny.kra@googlemail.com>
Sat, 9 Oct 2010 15:49:00 +0000 (15:49 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sat, 9 Oct 2010 15:49:00 +0000 (15:49 +0000)
Store pointer and length of the message in DelayedDiagnostic and hide the gory union details.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116153 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/DelayedDiagnostic.h
include/clang/Sema/Sema.h
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaExpr.cpp

index aedff4828fc75db5bdc69113c2ee3187d0bc2257..998e31b795b135ad5997292011ae699841cf4fcf 100644 (file)
@@ -119,14 +119,6 @@ public:
 
   SourceLocation Loc;
 
-  union {
-    /// Deprecation.
-    struct { NamedDecl *Decl; const char* Message; } DeprecationData;
-
-    /// Access control.
-    char AccessData[sizeof(AccessedEntity)];
-  };
-
   void destroy() {
     switch (Kind) {
     case Access: getAccessData().~AccessedEntity(); break;
@@ -135,14 +127,15 @@ public:
   }
 
   static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
-                                           NamedDecl *D,
-                                           const char *Msg) {
+                                           const NamedDecl *D,
+                                           llvm::StringRef Msg) {
     DelayedDiagnostic DD;
     DD.Kind = Deprecation;
     DD.Triggered = false;
     DD.Loc = Loc;
     DD.DeprecationData.Decl = D;
-    DD.DeprecationData.Message = Msg;
+    DD.DeprecationData.Message = Msg.data();
+    DD.DeprecationData.MessageLen = Msg.size();
     return DD;
   }
 
@@ -157,11 +150,37 @@ public:
   }
 
   AccessedEntity &getAccessData() {
+    assert(Kind == Access && "Not an access diagnostic.");
     return *reinterpret_cast<AccessedEntity*>(AccessData);
   }
   const AccessedEntity &getAccessData() const {
+    assert(Kind == Access && "Not an access diagnostic.");
     return *reinterpret_cast<const AccessedEntity*>(AccessData);
   }
+
+  const NamedDecl *getDeprecationDecl() const {
+    assert(Kind == Deprecation && "Not a deprecation diagnostic.");
+    return DeprecationData.Decl;
+  }
+
+  llvm::StringRef getDeprecationMessage() const {
+    assert(Kind == Deprecation && "Not a deprecation diagnostic.");
+    return llvm::StringRef(DeprecationData.Message,
+                           DeprecationData.MessageLen);
+  }
+
+private:
+  union {
+    /// Deprecation.
+    struct {
+      const NamedDecl *Decl;
+      const char *Message;
+      size_t MessageLen;
+    } DeprecationData;
+
+    /// Access control.
+    char AccessData[sizeof(AccessedEntity)];
+  };
 };
 
 }
index b5a092e75685036814b27d4140ad6f36a0d2e45e..889585ab0e120b92afb9bdc1d329d9537526358f 100644 (file)
@@ -1650,7 +1650,7 @@ public:
 
   ParsingDeclStackState PushParsingDeclaration();
   void PopParsingDeclaration(ParsingDeclStackState S, Decl *D);
-  void EmitDeprecationWarning(NamedDecl *D, const char *Message,
+  void EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
                               SourceLocation Loc);
 
   void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
index e9ee50fe75c0b56d1819caf2ce12dce228fd4b50..d5bd4f8944aa618b454fc77e9dafb1deae88c063 100644 (file)
@@ -2566,16 +2566,16 @@ void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
     return;
 
   DD.Triggered = true;
-  if (DD.DeprecationData.Message)
+  if (!DD.getDeprecationMessage().empty())
     Diag(DD.Loc, diag::warn_deprecated_message)
-      << DD.DeprecationData.Decl->getDeclName() 
-      << DD.DeprecationData.Message;
+      << DD.getDeprecationDecl()->getDeclName()
+      << DD.getDeprecationMessage();
   else
     Diag(DD.Loc, diag::warn_deprecated)
-      << DD.DeprecationData.Decl->getDeclName();
+      << DD.getDeprecationDecl()->getDeclName();
 }
 
-void Sema::EmitDeprecationWarning(NamedDecl *D, const char * Message,
+void Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
                                   SourceLocation Loc) {
   // Delay if we're currently parsing a declaration.
   if (ParsingDeclDepth) {
@@ -2587,7 +2587,7 @@ void Sema::EmitDeprecationWarning(NamedDecl *D, const char * Message,
   // Otherwise, don't warn if our current context is deprecated.
   if (isDeclDeprecated(cast<Decl>(CurContext)))
     return;
-  if (Message)
+  if (!Message.empty())
     Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 
                                              << Message;
   else
index e35b6c24551de2f2ed2ff66b6ca61ecafd869d3c..38287e4929559566213d50b77b48395c032d0c47 100644 (file)
@@ -57,11 +57,8 @@ using namespace sema;
 ///
 bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
   // See if the decl is deprecated.
-  if (const DeprecatedAttr *DA = D->getAttr<DeprecatedAttr>()) {
-    const char *Message = 
-      DA->getMessage().empty() ? 0 : DA->getMessage().data();
-    EmitDeprecationWarning(D, Message, Loc);
-  }
+  if (const DeprecatedAttr *DA = D->getAttr<DeprecatedAttr>())
+    EmitDeprecationWarning(D, DA->getMessage(), Loc);
 
   // See if the decl is unavailable
   if (const UnavailableAttr *UA = D->getAttr<UnavailableAttr>()) {
@@ -69,7 +66,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
       Diag(Loc, diag::err_unavailable) << D->getDeclName();
     else
       Diag(Loc, diag::err_unavailable_message) 
-        << D->getDeclName() << UA->getMessage().data();
+        << D->getDeclName() << UA->getMessage();
     Diag(D->getLocation(), diag::note_unavailable_here) << 0;
   }