[llvm-commits] [llvm] r168991 - in /llvm/trunk: include/llvm/DataLayout.h lib/VMCore/DataLayout.cpp

Patrik Hagglund patrik.h.hagglund at ericsson.com
Fri Nov 30 02:06:59 PST 2012


Author: patha
Date: Fri Nov 30 04:06:59 2012
New Revision: 168991

URL: http://llvm.org/viewvc/llvm-project?rev=168991&view=rev
Log:
More strict error checking in parseSpecifier + simplified code.

For example, don't allow empty strings to be passed to getInt.

Move asserts inside parseSpecifier. (One day we may want to pass parse
error messages to the user - from LLParser - instead of using asserts,
but keep the code simple until then. There have been an attempt to do
this. See r142288, which got reverted, and r142605.)

Modified:
    llvm/trunk/include/llvm/DataLayout.h
    llvm/trunk/lib/VMCore/DataLayout.cpp

Modified: llvm/trunk/include/llvm/DataLayout.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DataLayout.h?rev=168991&r1=168990&r2=168991&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DataLayout.h (original)
+++ llvm/trunk/include/llvm/DataLayout.h Fri Nov 30 04:06:59 2012
@@ -148,9 +148,9 @@
     return &align != &InvalidPointerElem;
   }
 
-  /// Parses a target data specification string. Returns an error message
-  /// if the string is malformed, or the empty string on success.
-  std::string parseSpecifier(StringRef LayoutDescription);
+  /// Parses a target data specification string. Assert if the string is
+  /// malformed.
+  void parseSpecifier(StringRef LayoutDescription);
 
 public:
   /// Default ctor.

Modified: llvm/trunk/lib/VMCore/DataLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/DataLayout.cpp?rev=168991&r1=168990&r2=168991&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/DataLayout.cpp (original)
+++ llvm/trunk/lib/VMCore/DataLayout.cpp Fri Nov 30 04:06:59 2012
@@ -174,35 +174,51 @@
   setAlignment(AGGREGATE_ALIGN, 0,  8,  0);  // struct
   setPointerAlignment(0, 8, 8, 8);
 
-  std::string errMsg = parseSpecifier(Desc);
-  assert(errMsg == "" && "Invalid target data layout string.");
-  (void)errMsg;
+  parseSpecifier(Desc);
+}
+
+/// Checked version of split, to ensure mandatory subparts.
+static std::pair<StringRef, StringRef> split(StringRef Str, char Separator) {
+  assert(!Str.empty() && "parse error, string can't be empty here");
+  std::pair<StringRef, StringRef> Split = Str.split(Separator);
+  assert((!Split.second.empty() || Split.first == Str) &&
+         "a trailing separator is not allowed");
+  return Split;
 }
 
 /// Get an unsinged integer, including error checks.
 static unsigned getInt(StringRef R) {
-  if (R.empty())
-    return 0;
   unsigned Result;
   bool error = R.getAsInteger(10, Result); (void)error;
   assert(!error && "not a number, or does not fit in an unsigned int");
   return Result;
 }
 
-std::string DataLayout::parseSpecifier(StringRef Desc) {
+/// Convert bits into bytes. Assert if not a byte width multiple.
+static unsigned inBytes(unsigned Bits) {
+  assert(Bits % 8 == 0 && "number of bits must be a byte width multiple");
+  return Bits / 8;
+}
+
+void DataLayout::parseSpecifier(StringRef Desc) {
 
   while (!Desc.empty()) {
-    std::pair<StringRef, StringRef> Split = Desc.split('-');
-    StringRef Token = Split.first;
+
+    // Split at '-'.
+    std::pair<StringRef, StringRef> Split = split(Desc, '-');
     Desc = Split.second;
 
-    Split = Token.split(':');
-    StringRef Specifier = Split.first;
-    Token = Split.second;
+    // Split at ':'.
+    Split = split(Split.first, ':');
+
+    // Aliases used below.
+    StringRef &Tok  = Split.first;  // Current token.
+    StringRef &Rest = Split.second; // The rest of the string.
 
-    assert(!Specifier.empty() && "Can't be empty here");
+    char Specifier = Tok.front();
+    Tok = Tok.substr(1);
 
-    switch (Specifier[0]) {
+    switch (Specifier) {
     case 'E':
       LittleEndian = false;
       break;
@@ -210,37 +226,28 @@
       LittleEndian = true;
       break;
     case 'p': {
-      unsigned AddrSpace = 0;
-      if (Specifier.size() > 1) {
-        AddrSpace = getInt(Specifier.substr(1));
-        if (AddrSpace > (1 << 24))
-          return "Invalid address space, must be a 24bit integer";
-      }
-      Split = Token.split(':');
-      unsigned PointerMemSizeBits = getInt(Split.first);
-      if (PointerMemSizeBits % 8 != 0)
-        return "invalid pointer size, must be an 8-bit multiple";
-
-      // Pointer ABI alignment.
-      Split = Split.second.split(':');
-      unsigned PointerABIAlignBits = getInt(Split.first);
-      if (PointerABIAlignBits % 8 != 0) {
-        return "invalid pointer ABI alignment, "
-               "must be an 8-bit multiple";
+      // Address space.
+      unsigned AddrSpace = Tok.empty() ? 0 : getInt(Tok);
+      assert(AddrSpace < 1 << 24 &&
+             "Invalid address space, must be a 24bit integer");
+
+      // Size.
+      Split = split(Rest, ':');
+      unsigned PointerMemSize = inBytes(getInt(Tok));
+
+      // ABI alignment.
+      Split = split(Rest, ':');
+      unsigned PointerABIAlign = inBytes(getInt(Tok));
+
+      // Preferred alignment.
+      unsigned PointerPrefAlign = PointerABIAlign;
+      if (!Rest.empty()) {
+        Split = split(Rest, ':');
+        PointerPrefAlign = inBytes(getInt(Tok));
       }
 
-      // Pointer preferred alignment.
-      Split = Split.second.split(':');
-      unsigned PointerPrefAlignBits = getInt(Split.first);
-      if (PointerPrefAlignBits % 8 != 0) {
-        return "invalid pointer preferred alignment, "
-               "must be an 8-bit multiple";
-      }
-
-      if (PointerPrefAlignBits == 0)
-        PointerPrefAlignBits = PointerABIAlignBits;
-      setPointerAlignment(AddrSpace, PointerABIAlignBits/8,
-                          PointerPrefAlignBits/8, PointerMemSizeBits/8);
+      setPointerAlignment(AddrSpace, PointerABIAlign, PointerPrefAlign,
+                          PointerMemSize);
       break;
     }
     case 'i':
@@ -249,8 +256,7 @@
     case 'a':
     case 's': {
       AlignTypeEnum AlignType;
-      char field = Specifier[0];
-      switch (field) {
+      switch (Specifier) {
       default:
       case 'i': AlignType = INTEGER_ALIGN; break;
       case 'v': AlignType = VECTOR_ALIGN; break;
@@ -258,59 +264,44 @@
       case 'a': AlignType = AGGREGATE_ALIGN; break;
       case 's': AlignType = STACK_ALIGN; break;
       }
-      unsigned Size = getInt(Specifier.substr(1));
-
-      Split = Token.split(':');
-      unsigned ABIAlignBits = getInt(Split.first);
-      if (ABIAlignBits % 8 != 0) {
-        return std::string("invalid ") + field +"-abi-alignment field, "
-               "must be an 8-bit multiple";
-      }
-      unsigned ABIAlign = ABIAlignBits / 8;
 
-      Split = Split.second.split(':');
+      // Bit size.
+      unsigned Size = Tok.empty() ? 0 : getInt(Tok);
 
-      unsigned PrefAlignBits = getInt(Split.first);
-      if (PrefAlignBits % 8 != 0) {
-        return std::string("invalid ") + field +"-preferred-alignment field, "
-               "must be an 8-bit multiple";
+      // ABI alignment.
+      Split = split(Rest, ':');
+      unsigned ABIAlign = inBytes(getInt(Tok));
+
+      // Preferred alignment.
+      unsigned PrefAlign = ABIAlign;
+      if (!Rest.empty()) {
+        Split = split(Rest, ':');
+        PrefAlign = inBytes(getInt(Tok));
       }
-      unsigned PrefAlign = PrefAlignBits / 8;
-      if (PrefAlign == 0)
-        PrefAlign = ABIAlign;
+
       setAlignment(AlignType, ABIAlign, PrefAlign, Size);
 
       break;
     }
     case 'n':  // Native integer types.
-      Specifier = Specifier.substr(1);
-      do {
-        unsigned Width = getInt(Specifier);
-        if (Width == 0) {
-          return std::string("invalid native integer size \'") +
-            Specifier.str() + "\', must be a non-zero integer.";
-        }
+      for (;;) {
+        unsigned Width = getInt(Tok);
+        assert(Width != 0 && "width must be non-zero");
         LegalIntWidths.push_back(Width);
-        Split = Token.split(':');
-        Specifier = Split.first;
-        Token = Split.second;
-      } while (!Specifier.empty() || !Token.empty());
+        if (Rest.empty())
+          break;
+        Split = split(Rest, ':');
+      }
       break;
     case 'S': { // Stack natural alignment.
-      unsigned StackNaturalAlignBits = getInt(Specifier.substr(1));
-      if (StackNaturalAlignBits % 8 != 0) {
-        return "invalid natural stack alignment (S-field), "
-               "must be an 8-bit multiple";
-      }
-      StackNaturalAlign = StackNaturalAlignBits / 8;
+      StackNaturalAlign = inBytes(getInt(Tok));
       break;
     }
     default:
+      llvm_unreachable("Unknown specifier in datalayout string");
       break;
     }
   }
-
-  return "";
 }
 
 /// Default ctor.





More information about the llvm-commits mailing list