<br><br><div class="gmail_quote">On Fri, Jan 20, 2012 at 10:31 AM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Fri, Jan 20, 2012 at 9:56 AM, Kostya Serebryany <<a href="mailto:kcc@google.com">kcc@google.com</a>> wrote:<br>
> Author: kcc<br>
> Date: Fri Jan 20 11:56:17 2012<br>
> New Revision: 148553<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=148553&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=148553&view=rev</a><br>
> Log:<br>
> Extend Attributes to 64 bits<br>
><br>
> Problem: LLVM needs more function attributes than currently available (32 bits).<br>
> One such proposed attribute is "address_safety", which shows that a function is being checked for address safety (by AddressSanitizer, SAFECode, etc).<br>
><br>
> Solution:<br>
> - extend the Attributes from 32 bits to 64-bits<br>
> - wrap the object into a class so that unsigned is never erroneously used instead<br>
> - change "unsigned" to "Attributes" throughout the code, including one place in clang.<br>
> - the class has no "operator uint64 ()", but it has "uint64_t Raw() " to support packing/unpacking.<br>
> - the class has "safe operator bool()" to support the common idiom:  if (Attributes attr = getAttrs()) useAttrs(attr);<br>
<br>
Oh, I didn't notice you'd done anything like this in the CR version.<br>
Just for the record - your implementation isn't terribly safe. It's<br>
safer than 'bool', that's for sure, but still has some limitations.<br>
<br>
In case it's of interest, I had included in a previous CR (that was<br>
never signed off) a full implementation of the Safe Bool style<br>
documented here ( <a href="http://www.artima.com/cppsource/safebool.html" target="_blank">http://www.artima.com/cppsource/safebool.html</a> ) to<br></blockquote><div><br></div><div>Yea, I've read this document. Impressive! </div>
<div>I've chosen void* as the simplest and safe enough idiom. </div><div>I don't think that code like </div><div>   Attributes attr;</div><div>   delete attr;</div><div>is likely to appear. Even if so, it will be detected by the run-time library. </div>
<div><br></div><div>If/when we have a reusable safe bool class, we can use it here, </div><div>but I thought that adding such class into this patch would be an overkill. </div><div><br></div><div>--kcc </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

be used by StringRef (or Twine) or something... if that'd be of<br>
interest I can pry it out as a separate patch.<br>
<br>
(to find my original patch you can probably look for something from<br>
this email address with twine and stringref in the title and a file<br>
attachment - it was sent out probably 6-9 months ago. I've been<br>
meaning to update it recently to get it back up to mainline<br>
compatibility)<br>
<br>
- David<br>
<br>
> - The CTOR from uint64_t is marked explicit, so I had to add a few explicit CTOR calls<br>
> - Add the new attribute "address_safety". Doing it in the same commit to check that attributes beyond first 32 bits actually work.<br>
> - Some of the functions from the Attribute namespace are worth moving inside the class, but I'd prefer to have it as a separate commit.<br>
><br>
> Tested:<br>
> "make check" on Linux (32-bit and 64-bit) and Mac (10.6)<br>
> built/run spec CPU 2006 on Linux with clang -O2.<br>
><br>
><br>
> This change will break clang build in lib/CodeGen/CGCall.cpp.<br>
> The following patch will fix it.<br>
><br>
> Modified:<br>
>    llvm/trunk/docs/LangRef.html<br>
>    llvm/trunk/include/llvm-c/Core.h<br>
>    llvm/trunk/include/llvm/Attributes.h<br>
>    llvm/trunk/lib/AsmParser/LLLexer.cpp<br>
>    llvm/trunk/lib/AsmParser/LLParser.cpp<br>
>    llvm/trunk/lib/AsmParser/LLParser.h<br>
>    llvm/trunk/lib/AsmParser/LLToken.h<br>
>    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp<br>
>    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp<br>
>    llvm/trunk/lib/CodeGen/Analysis.cpp<br>
>    llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp<br>
>    llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp<br>
>    llvm/trunk/lib/VMCore/Attributes.cpp<br>
>    llvm/trunk/lib/VMCore/Core.cpp<br>
>    llvm/trunk/lib/VMCore/Verifier.cpp<br>
>    llvm/trunk/utils/llvm.grm<br>
><br>
> Modified: llvm/trunk/docs/LangRef.html<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/docs/LangRef.html (original)<br>
> +++ llvm/trunk/docs/LangRef.html Fri Jan 20 11:56:17 2012<br>
> @@ -1143,6 +1143,10 @@<br>
>  </pre><br>
><br>
>  <dl><br>
> +  <dt><tt><b>address_safety</b></tt></dt><br>
> +  <dd>This attribute indicates that the address safety analysis<br>
> +  is enabled for this function.  </dd><br>
> +<br>
>   <dt><tt><b>alignstack(&lt;<em>n</em>&gt;)</b></tt></dt><br>
>   <dd>This attribute indicates that, when emitting the prologue and epilogue,<br>
>       the backend should forcibly align the stack pointer. Specify the<br>
><br>
> Modified: llvm/trunk/include/llvm-c/Core.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/include/llvm-c/Core.h (original)<br>
> +++ llvm/trunk/include/llvm-c/Core.h Fri Jan 20 11:56:17 2012<br>
> @@ -118,7 +118,8 @@<br>
>     LLVMStackAlignment = 7<<26,<br>
>     LLVMReturnsTwice = 1 << 29,<br>
>     LLVMUWTable = 1 << 30,<br>
> -    LLVMNonLazyBind = 1 << 31<br>
> +    LLVMNonLazyBind = 1U << 31,<br>
> +    LLVMAddressSafety = 1ULL << 32,<br>
>  } LLVMAttribute;<br>
><br>
>  typedef enum {<br>
><br>
> Modified: llvm/trunk/include/llvm/Attributes.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Attributes.h?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Attributes.h?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/include/llvm/Attributes.h (original)<br>
> +++ llvm/trunk/include/llvm/Attributes.h Fri Jan 20 11:56:17 2012<br>
> @@ -23,7 +23,47 @@<br>
>  class Type;<br>
><br>
>  /// Attributes - A bitset of attributes.<br>
> -typedef unsigned Attributes;<br>
> +class Attributes {<br>
> + public:<br>
> +  Attributes() : Bits(0) { }<br>
> +  explicit Attributes(uint64_t Val) : Bits(Val) { }<br>
> +  Attributes(const Attributes &Attrs) : Bits(Attrs.Bits) { }<br>
> +  // This is a "safe bool() operator".<br>
> +  operator const void *() const { return Bits ? this : 0; }<br>
> +  bool isEmptyOrSingleton() const { return (Bits & (Bits - 1)) == 0; }<br>
> +  Attributes &operator = (const Attributes &Attrs) {<br>
> +    Bits = Attrs.Bits;<br>
> +    return *this;<br>
> +  }<br>
> +  bool operator == (const Attributes &Attrs) const {<br>
> +    return Bits == Attrs.Bits;<br>
> +  }<br>
> +  bool operator != (const Attributes &Attrs) const {<br>
> +    return Bits != Attrs.Bits;<br>
> +  }<br>
> +  Attributes operator | (const Attributes &Attrs) const {<br>
> +    return Attributes(Bits | Attrs.Bits);<br>
> +  }<br>
> +  Attributes operator & (const Attributes &Attrs) const {<br>
> +    return Attributes(Bits & Attrs.Bits);<br>
> +  }<br>
> +  Attributes operator ^ (const Attributes &Attrs) const {<br>
> +    return Attributes(Bits ^ Attrs.Bits);<br>
> +  }<br>
> +  Attributes &operator |= (const Attributes &Attrs) {<br>
> +    Bits |= Attrs.Bits;<br>
> +    return *this;<br>
> +  }<br>
> +  Attributes &operator &= (const Attributes &Attrs) {<br>
> +    Bits &= Attrs.Bits;<br>
> +    return *this;<br>
> +  }<br>
> +  Attributes operator ~ () const { return Attributes(~Bits); }<br>
> +  uint64_t Raw() const { return Bits; }<br>
> + private:<br>
> +  // Currently, we need less than 64 bits.<br>
> +  uint64_t Bits;<br>
> +};<br>
><br>
>  namespace Attribute {<br>
><br>
> @@ -33,44 +73,45 @@<br>
>  /// results or the function itself.<br>
>  /// @brief Function attributes.<br>
><br>
> -const Attributes None      = 0;     ///< No attributes have been set<br>
> -const Attributes ZExt      = 1<<0;  ///< Zero extended before/after call<br>
> -const Attributes SExt      = 1<<1;  ///< Sign extended before/after call<br>
> -const Attributes NoReturn  = 1<<2;  ///< Mark the function as not returning<br>
> -const Attributes InReg     = 1<<3;  ///< Force argument to be passed in register<br>
> -const Attributes StructRet = 1<<4;  ///< Hidden pointer to structure to return<br>
> -const Attributes NoUnwind  = 1<<5;  ///< Function doesn't unwind stack<br>
> -const Attributes NoAlias   = 1<<6;  ///< Considered to not alias after call<br>
> -const Attributes ByVal     = 1<<7;  ///< Pass structure by value<br>
> -const Attributes Nest      = 1<<8;  ///< Nested function static chain<br>
> -const Attributes ReadNone  = 1<<9;  ///< Function does not access memory<br>
> -const Attributes ReadOnly  = 1<<10; ///< Function only reads from memory<br>
> -const Attributes NoInline        = 1<<11; ///< inline=never<br>
> -const Attributes AlwaysInline    = 1<<12; ///< inline=always<br>
> -const Attributes OptimizeForSize = 1<<13; ///< opt_size<br>
> -const Attributes StackProtect    = 1<<14; ///< Stack protection.<br>
> -const Attributes StackProtectReq = 1<<15; ///< Stack protection required.<br>
> -const Attributes Alignment = 31<<16; ///< Alignment of parameter (5 bits)<br>
> +const Attributes None      (0);     ///< No attributes have been set<br>
> +const Attributes ZExt      (1<<0);  ///< Zero extended before/after call<br>
> +const Attributes SExt      (1<<1);  ///< Sign extended before/after call<br>
> +const Attributes NoReturn  (1<<2);  ///< Mark the function as not returning<br>
> +const Attributes InReg     (1<<3);  ///< Force argument to be passed in register<br>
> +const Attributes StructRet (1<<4);  ///< Hidden pointer to structure to return<br>
> +const Attributes NoUnwind  (1<<5);  ///< Function doesn't unwind stack<br>
> +const Attributes NoAlias   (1<<6);  ///< Considered to not alias after call<br>
> +const Attributes ByVal     (1<<7);  ///< Pass structure by value<br>
> +const Attributes Nest      (1<<8);  ///< Nested function static chain<br>
> +const Attributes ReadNone  (1<<9);  ///< Function does not access memory<br>
> +const Attributes ReadOnly  (1<<10); ///< Function only reads from memory<br>
> +const Attributes NoInline        (1<<11); ///< inline=never<br>
> +const Attributes AlwaysInline    (1<<12); ///< inline=always<br>
> +const Attributes OptimizeForSize (1<<13); ///< opt_size<br>
> +const Attributes StackProtect    (1<<14); ///< Stack protection.<br>
> +const Attributes StackProtectReq (1<<15); ///< Stack protection required.<br>
> +const Attributes Alignment (31<<16); ///< Alignment of parameter (5 bits)<br>
>                                      // stored as log2 of alignment with +1 bias<br>
>                                      // 0 means unaligned different from align 1<br>
> -const Attributes NoCapture = 1<<21; ///< Function creates no aliases of pointer<br>
> -const Attributes NoRedZone = 1<<22; /// disable redzone<br>
> -const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point<br>
> +const Attributes NoCapture (1<<21); ///< Function creates no aliases of pointer<br>
> +const Attributes NoRedZone (1<<22); /// disable redzone<br>
> +const Attributes NoImplicitFloat (1<<23); /// disable implicit floating point<br>
>                                           /// instructions.<br>
> -const Attributes Naked           = 1<<24; ///< Naked function<br>
> -const Attributes InlineHint      = 1<<25; ///< source said inlining was<br>
> +const Attributes Naked           (1<<24); ///< Naked function<br>
> +const Attributes InlineHint      (1<<25); ///< source said inlining was<br>
>                                           ///desirable<br>
> -const Attributes StackAlignment  = 7<<26; ///< Alignment of stack for<br>
> +const Attributes StackAlignment  (7<<26); ///< Alignment of stack for<br>
>                                           ///function (3 bits) stored as log2<br>
>                                           ///of alignment with +1 bias<br>
>                                           ///0 means unaligned (different from<br>
>                                           ///alignstack(1))<br>
> -const Attributes ReturnsTwice    = 1<<29; ///< Function can return twice<br>
> -const Attributes UWTable     = 1<<30;     ///< Function must be in a unwind<br>
> +const Attributes ReturnsTwice    (1<<29); ///< Function can return twice<br>
> +const Attributes UWTable     (1<<30);     ///< Function must be in a unwind<br>
>                                           ///table<br>
> -const Attributes NonLazyBind = 1U<<31;    ///< Function is called early and/or<br>
> +const Attributes NonLazyBind (1U<<31);    ///< Function is called early and/or<br>
>                                           ///  often, so lazy binding isn't<br>
>                                           ///  worthwhile.<br>
> +const Attributes AddressSafety(1ULL<<32); ///< Address safety checking is on.<br>
><br>
>  /// Note that uwtable is about the ABI or the user mandating an entry in the<br>
>  /// unwind table. The nounwind attribute is about an exception passing by the<br>
> @@ -92,7 +133,7 @@<br>
>  const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |<br>
>   NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |<br>
>   NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment |<br>
> -  UWTable | NonLazyBind | ReturnsTwice;<br>
> +  UWTable | NonLazyBind | ReturnsTwice | AddressSafety;<br>
><br>
>  /// @brief Parameter attributes that do not apply to vararg call arguments.<br>
>  const Attributes VarArgsIncompatible = StructRet;<br>
> @@ -113,20 +154,20 @@<br>
>  inline Attributes constructAlignmentFromInt(unsigned i) {<br>
>   // Default alignment, allow the target to define how to align it.<br>
>   if (i == 0)<br>
> -    return 0;<br>
> +    return None;<br>
><br>
>   assert(isPowerOf2_32(i) && "Alignment must be a power of two.");<br>
>   assert(i <= 0x40000000 && "Alignment too large.");<br>
> -  return (Log2_32(i)+1) << 16;<br>
> +  return Attributes((Log2_32(i)+1) << 16);<br>
>  }<br>
><br>
>  /// This returns the alignment field of an attribute as a byte alignment value.<br>
>  inline unsigned getAlignmentFromAttrs(Attributes A) {<br>
>   Attributes Align = A & Attribute::Alignment;<br>
> -  if (Align == 0)<br>
> +  if (!Align)<br>
>     return 0;<br>
><br>
> -  return 1U << ((Align >> 16) - 1);<br>
> +  return 1U << ((Align.Raw() >> 16) - 1);<br>
>  }<br>
><br>
>  /// This turns an int stack alignment (which must be a power of 2) into<br>
> @@ -134,21 +175,21 @@<br>
>  inline Attributes constructStackAlignmentFromInt(unsigned i) {<br>
>   // Default alignment, allow the target to define how to align it.<br>
>   if (i == 0)<br>
> -    return 0;<br>
> +    return None;<br>
><br>
>   assert(isPowerOf2_32(i) && "Alignment must be a power of two.");<br>
>   assert(i <= 0x100 && "Alignment too large.");<br>
> -  return (Log2_32(i)+1) << 26;<br>
> +  return Attributes((Log2_32(i)+1) << 26);<br>
>  }<br>
><br>
>  /// This returns the stack alignment field of an attribute as a byte alignment<br>
>  /// value.<br>
>  inline unsigned getStackAlignmentFromAttrs(Attributes A) {<br>
>   Attributes StackAlign = A & Attribute::StackAlignment;<br>
> -  if (StackAlign == 0)<br>
> +  if (!StackAlign)<br>
>     return 0;<br>
><br>
> -  return 1U << ((StackAlign >> 26) - 1);<br>
> +  return 1U << ((StackAlign.Raw() >> 26) - 1);<br>
>  }<br>
><br>
><br>
> @@ -242,7 +283,7 @@<br>
>   /// paramHasAttr - Return true if the specified parameter index has the<br>
>   /// specified attribute set.<br>
>   bool paramHasAttr(unsigned Idx, Attributes Attr) const {<br>
> -    return (getAttributes(Idx) & Attr) != 0;<br>
> +    return getAttributes(Idx) & Attr;<br>
>   }<br>
><br>
>   /// getParamAlignment - Return the alignment for the specified function<br>
><br>
> Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)<br>
> +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Fri Jan 20 11:56:17 2012<br>
> @@ -548,6 +548,7 @@<br>
>   KEYWORD(noimplicitfloat);<br>
>   KEYWORD(naked);<br>
>   KEYWORD(nonlazybind);<br>
> +  KEYWORD(address_safety);<br>
><br>
>   KEYWORD(type);<br>
>   KEYWORD(opaque);<br>
><br>
> Modified: llvm/trunk/lib/AsmParser/LLParser.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/AsmParser/LLParser.cpp (original)<br>
> +++ llvm/trunk/lib/AsmParser/LLParser.cpp Fri Jan 20 11:56:17 2012<br>
> @@ -874,7 +874,7 @@<br>
>  /// ParseOptionalAttrs - Parse a potentially empty attribute list.  AttrKind<br>
>  /// indicates what kind of attribute list this is: 0: function arg, 1: result,<br>
>  /// 2: function attr.<br>
> -bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {<br>
> +bool LLParser::ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind) {<br>
>   Attrs = Attribute::None;<br>
>   LocTy AttrLoc = Lex.getLoc();<br>
><br>
> @@ -919,6 +919,7 @@<br>
>     case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;<br>
>     case lltok::kw_naked:           Attrs |= Attribute::Naked; break;<br>
>     case lltok::kw_nonlazybind:     Attrs |= Attribute::NonLazyBind; break;<br>
> +    case lltok::kw_address_safety:  Attrs |= Attribute::AddressSafety; break;<br>
><br>
>     case lltok::kw_alignstack: {<br>
>       unsigned Alignment;<br>
> @@ -1353,8 +1354,8 @@<br>
>     // Parse the argument.<br>
>     LocTy ArgLoc;<br>
>     Type *ArgTy = 0;<br>
> -    unsigned ArgAttrs1 = Attribute::None;<br>
> -    unsigned ArgAttrs2 = Attribute::None;<br>
> +    Attributes ArgAttrs1;<br>
> +    Attributes ArgAttrs2;<br>
>     Value *V;<br>
>     if (ParseType(ArgTy, ArgLoc))<br>
>       return true;<br>
> @@ -1394,7 +1395,7 @@<br>
>   } else {<br>
>     LocTy TypeLoc = Lex.getLoc();<br>
>     Type *ArgTy = 0;<br>
> -    unsigned Attrs;<br>
> +    Attributes Attrs;<br>
>     std::string Name;<br>
><br>
>     if (ParseType(ArgTy) ||<br>
> @@ -1461,7 +1462,7 @@<br>
>   for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {<br>
>     if (!ArgList[i].Name.empty())<br>
>       return Error(ArgList[i].Loc, "argument name invalid in function type");<br>
> -    if (ArgList[i].Attrs != 0)<br>
> +    if (ArgList[i].Attrs)<br>
>       return Error(ArgList[i].Loc,<br>
>                    "argument attributes invalid in function type");<br>
>   }<br>
> @@ -2586,7 +2587,8 @@<br>
>   LocTy LinkageLoc = Lex.getLoc();<br>
>   unsigned Linkage;<br>
><br>
> -  unsigned Visibility, RetAttrs;<br>
> +  unsigned Visibility;<br>
> +  Attributes RetAttrs;<br>
>   CallingConv::ID CC;<br>
>   Type *RetType = 0;<br>
>   LocTy RetTypeLoc = Lex.getLoc();<br>
> @@ -2650,7 +2652,7 @@<br>
><br>
>   SmallVector<ArgInfo, 8> ArgList;<br>
>   bool isVarArg;<br>
> -  unsigned FuncAttrs;<br>
> +  Attributes FuncAttrs;<br>
>   std::string Section;<br>
>   unsigned Alignment;<br>
>   std::string GC;<br>
> @@ -3162,7 +3164,7 @@<br>
>  ///       OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue<br>
>  bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {<br>
>   LocTy CallLoc = Lex.getLoc();<br>
> -  unsigned RetAttrs, FnAttrs;<br>
> +  Attributes RetAttrs, FnAttrs;<br>
>   CallingConv::ID CC;<br>
>   Type *RetType = 0;<br>
>   LocTy RetTypeLoc;<br>
> @@ -3561,7 +3563,7 @@<br>
>  ///       ParameterList OptionalAttrs<br>
>  bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,<br>
>                          bool isTail) {<br>
> -  unsigned RetAttrs, FnAttrs;<br>
> +  Attributes RetAttrs, FnAttrs;<br>
>   CallingConv::ID CC;<br>
>   Type *RetType = 0;<br>
>   LocTy RetTypeLoc;<br>
><br>
> Modified: llvm/trunk/lib/AsmParser/LLParser.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/AsmParser/LLParser.h (original)<br>
> +++ llvm/trunk/lib/AsmParser/LLParser.h Fri Jan 20 11:56:17 2012<br>
> @@ -15,6 +15,7 @@<br>
>  #define LLVM_ASMPARSER_LLPARSER_H<br>
><br>
>  #include "LLLexer.h"<br>
> +#include "llvm/Attributes.h"<br>
>  #include "llvm/Instructions.h"<br>
>  #include "llvm/Module.h"<br>
>  #include "llvm/Type.h"<br>
> @@ -171,7 +172,7 @@<br>
>       return ParseUInt32(Val);<br>
>     }<br>
>     bool ParseOptionalAddrSpace(unsigned &AddrSpace);<br>
> -    bool ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind);<br>
> +    bool ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind);<br>
>     bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage);<br>
>     bool ParseOptionalLinkage(unsigned &Linkage) {<br>
>       bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage);<br>
> @@ -304,8 +305,8 @@<br>
>     struct ParamInfo {<br>
>       LocTy Loc;<br>
>       Value *V;<br>
> -      unsigned Attrs;<br>
> -      ParamInfo(LocTy loc, Value *v, unsigned attrs)<br>
> +      Attributes Attrs;<br>
> +      ParamInfo(LocTy loc, Value *v, Attributes attrs)<br>
>         : Loc(loc), V(v), Attrs(attrs) {}<br>
>     };<br>
>     bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,<br>
> @@ -325,9 +326,9 @@<br>
>     struct ArgInfo {<br>
>       LocTy Loc;<br>
>       Type *Ty;<br>
> -      unsigned Attrs;<br>
> +      Attributes Attrs;<br>
>       std::string Name;<br>
> -      ArgInfo(LocTy L, Type *ty, unsigned Attr, const std::string &N)<br>
> +      ArgInfo(LocTy L, Type *ty, Attributes Attr, const std::string &N)<br>
>         : Loc(L), Ty(ty), Attrs(Attr), Name(N) {}<br>
>     };<br>
>     bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &isVarArg);<br>
><br>
> Modified: llvm/trunk/lib/AsmParser/LLToken.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/AsmParser/LLToken.h (original)<br>
> +++ llvm/trunk/lib/AsmParser/LLToken.h Fri Jan 20 11:56:17 2012<br>
> @@ -102,6 +102,7 @@<br>
>     kw_noimplicitfloat,<br>
>     kw_naked,<br>
>     kw_nonlazybind,<br>
> +    kw_address_safety,<br>
><br>
>     kw_type,<br>
>     kw_opaque,<br>
><br>
> Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)<br>
> +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Fri Jan 20 11:56:17 2012<br>
> @@ -461,8 +461,8 @@<br>
>       // If Function attributes are using index 0 then transfer them<br>
>       // to index ~0. Index 0 is used for return value attributes but used to be<br>
>       // used for function attributes.<br>
> -      Attributes RetAttribute = Attribute::None;<br>
> -      Attributes FnAttribute = Attribute::None;<br>
> +      Attributes RetAttribute;<br>
> +      Attributes FnAttribute;<br>
>       for (unsigned i = 0, e = Record.size(); i != e; i += 2) {<br>
>         // FIXME: remove in LLVM 3.0<br>
>         // The alignment is stored as a 16-bit raw value from bits 31--16.<br>
> @@ -472,23 +472,24 @@<br>
>         if (Alignment && !isPowerOf2_32(Alignment))<br>
>           return Error("Alignment is not a power of two.");<br>
><br>
> -        Attributes ReconstitutedAttr = Record[i+1] & 0xffff;<br>
> +        Attributes ReconstitutedAttr(Record[i+1] & 0xffff);<br>
>         if (Alignment)<br>
>           ReconstitutedAttr |= Attribute::constructAlignmentFromInt(Alignment);<br>
> -        ReconstitutedAttr |= (Record[i+1] & (0xffffull << 32)) >> 11;<br>
> -        Record[i+1] = ReconstitutedAttr;<br>
> +        ReconstitutedAttr |=<br>
> +            Attributes((Record[i+1] & (0xffffull << 32)) >> 11);<br>
><br>
> +        Record[i+1] = ReconstitutedAttr.Raw();<br>
>         if (Record[i] == 0)<br>
> -          RetAttribute = Record[i+1];<br>
> +          RetAttribute = ReconstitutedAttr;<br>
>         else if (Record[i] == ~0U)<br>
> -          FnAttribute = Record[i+1];<br>
> +          FnAttribute = ReconstitutedAttr;<br>
>       }<br>
><br>
> -      unsigned OldRetAttrs = (Attribute::NoUnwind|Attribute::NoReturn|<br>
> +      Attributes OldRetAttrs = (Attribute::NoUnwind|Attribute::NoReturn|<br>
>                               Attribute::ReadOnly|Attribute::ReadNone);<br>
><br>
>       if (FnAttribute == Attribute::None && RetAttribute != Attribute::None &&<br>
> -          (RetAttribute & OldRetAttrs) != 0) {<br>
> +          (RetAttribute & OldRetAttrs)) {<br>
>         if (FnAttribute == Attribute::None) { // add a slot so they get added.<br>
>           Record.push_back(~0U);<br>
>           Record.push_back(0);<br>
> @@ -505,8 +506,9 @@<br>
>         } else if (Record[i] == ~0U) {<br>
>           if (FnAttribute != Attribute::None)<br>
>             Attrs.push_back(AttributeWithIndex::get(~0U, FnAttribute));<br>
> -        } else if (Record[i+1] != Attribute::None)<br>
> -          Attrs.push_back(AttributeWithIndex::get(Record[i], Record[i+1]));<br>
> +        } else if (Attributes(Record[i+1]) != Attribute::None)<br>
> +          Attrs.push_back(AttributeWithIndex::get(Record[i],<br>
> +                                                  Attributes(Record[i+1])));<br>
>       }<br>
><br>
>       MAttributes.push_back(AttrListPtr::get(Attrs.begin(), Attrs.end()));<br>
><br>
> Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)<br>
> +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Fri Jan 20 11:56:17 2012<br>
> @@ -179,10 +179,11 @@<br>
>       // Store the alignment in the bitcode as a 16-bit raw value instead of a<br>
>       // 5-bit log2 encoded value. Shift the bits above the alignment up by<br>
>       // 11 bits.<br>
> -      uint64_t FauxAttr = PAWI.Attrs & 0xffff;<br>
> +      uint64_t FauxAttr = PAWI.Attrs.Raw() & 0xffff;<br>
>       if (PAWI.Attrs & Attribute::Alignment)<br>
> -        FauxAttr |= (1ull<<16)<<(((PAWI.Attrs & Attribute::Alignment)-1) >> 16);<br>
> -      FauxAttr |= (PAWI.Attrs & (0x3FFull << 21)) << 11;<br>
> +        FauxAttr |= (1ull<<16)<<<br>
> +            (((PAWI.Attrs & Attribute::Alignment).Raw()-1) >> 16);<br>
> +      FauxAttr |= (PAWI.Attrs.Raw() & (0x3FFull << 21)) << 11;<br>
><br>
>       Record.push_back(FauxAttr);<br>
>     }<br>
><br>
> Modified: llvm/trunk/lib/CodeGen/Analysis.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Analysis.cpp?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Analysis.cpp?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/CodeGen/Analysis.cpp (original)<br>
> +++ llvm/trunk/lib/CodeGen/Analysis.cpp Fri Jan 20 11:56:17 2012<br>
> @@ -259,7 +259,7 @@<br>
>   // Conservatively require the attributes of the call to match those of<br>
>   // the return. Ignore noalias because it doesn't affect the call sequence.<br>
>   const Function *F = ExitBB->getParent();<br>
> -  unsigned CallerRetAttr = F->getAttributes().getRetAttributes();<br>
> +  Attributes CallerRetAttr = F->getAttributes().getRetAttributes();<br>
>   if ((CalleeRetAttr ^ CallerRetAttr) & ~Attribute::NoAlias)<br>
>     return false;<br>
><br>
> @@ -299,7 +299,7 @@<br>
><br>
>   // Conservatively require the attributes of the call to match those of<br>
>   // the return. Ignore noalias because it doesn't affect the call sequence.<br>
> -  unsigned CallerRetAttr = F->getAttributes().getRetAttributes();<br>
> +  Attributes CallerRetAttr = F->getAttributes().getRetAttributes();<br>
>   if (CallerRetAttr & ~Attribute::NoAlias)<br>
>     return false;<br>
><br>
><br>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)<br>
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Fri Jan 20 11:56:17 2012<br>
> @@ -1063,7 +1063,7 @@<br>
>     if (!CastInst::isCastable(ActTy, ParamTy))<br>
>       return false;   // Cannot transform this parameter value.<br>
><br>
> -    unsigned Attrs = CallerPAL.getParamAttributes(i + 1);<br>
> +    Attributes Attrs = CallerPAL.getParamAttributes(i + 1);<br>
>     if (Attrs & Attribute::typeIncompatible(ParamTy))<br>
>       return false;   // Attribute not compatible with transformed value.<br>
><br>
> @@ -1392,4 +1392,3 @@<br>
>   CS.setCalledFunction(NewCallee);<br>
>   return CS.getInstruction();<br>
>  }<br>
> -<br>
><br>
> Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original)<br>
> +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Fri Jan 20 11:56:17 2012<br>
> @@ -619,7 +619,7 @@<br>
>   // It's not safe to eliminate the sign / zero extension of the return value.<br>
>   // See llvm::isInTailCallPosition().<br>
>   const Function *F = BB->getParent();<br>
> -  unsigned CallerRetAttr = F->getAttributes().getRetAttributes();<br>
> +  Attributes CallerRetAttr = F->getAttributes().getRetAttributes();<br>
>   if ((CallerRetAttr & Attribute::ZExt) || (CallerRetAttr & Attribute::SExt))<br>
>     return false;<br>
><br>
> @@ -674,7 +674,7 @@<br>
><br>
>     // Conservatively require the attributes of the call to match those of the<br>
>     // return. Ignore noalias because it doesn't affect the call sequence.<br>
> -    unsigned CalleeRetAttr = CS.getAttributes().getRetAttributes();<br>
> +    Attributes CalleeRetAttr = CS.getAttributes().getRetAttributes();<br>
>     if ((CalleeRetAttr ^ CallerRetAttr) & ~Attribute::NoAlias)<br>
>       continue;<br>
><br>
><br>
> Modified: llvm/trunk/lib/VMCore/Attributes.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Attributes.cpp?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Attributes.cpp?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/VMCore/Attributes.cpp (original)<br>
> +++ llvm/trunk/lib/VMCore/Attributes.cpp Fri Jan 20 11:56:17 2012<br>
> @@ -76,6 +76,8 @@<br>
>     Result += "naked ";<br>
>   if (Attrs & Attribute::NonLazyBind)<br>
>     Result += "nonlazybind ";<br>
> +  if (Attrs & Attribute::AddressSafety)<br>
> +    Result += "address_safety ";<br>
>   if (Attrs & Attribute::StackAlignment) {<br>
>     Result += "alignstack(";<br>
>     Result += utostr(Attribute::getStackAlignmentFromAttrs(Attrs));<br>
> @@ -152,8 +154,10 @@<br>
>   }<br>
>   static void Profile(FoldingSetNodeID &ID, const AttributeWithIndex *Attr,<br>
>                       unsigned NumAttrs) {<br>
> -    for (unsigned i = 0; i != NumAttrs; ++i)<br>
> -      ID.AddInteger(uint64_t(Attr[i].Attrs) << 32 | unsigned(Attr[i].Index));<br>
> +    for (unsigned i = 0; i != NumAttrs; ++i) {<br>
> +      ID.AddInteger(Attr[i].Attrs.Raw());<br>
> +      ID.AddInteger(Attr[i].Index);<br>
> +    }<br>
>   }<br>
>  };<br>
>  }<br>
><br>
> Modified: llvm/trunk/lib/VMCore/Core.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/VMCore/Core.cpp (original)<br>
> +++ llvm/trunk/lib/VMCore/Core.cpp Fri Jan 20 11:56:17 2012<br>
> @@ -13,6 +13,7 @@<br>
>  //===----------------------------------------------------------------------===//<br>
><br>
>  #include "llvm-c/Core.h"<br>
> +#include "llvm/Attributes.h"<br>
>  #include "llvm/Bitcode/ReaderWriter.h"<br>
>  #include "llvm/Constants.h"<br>
>  #include "llvm/DerivedTypes.h"<br>
> @@ -1350,14 +1351,14 @@<br>
>  void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) {<br>
>   Function *Func = unwrap<Function>(Fn);<br>
>   const AttrListPtr PAL = Func->getAttributes();<br>
> -  const AttrListPtr PALnew = PAL.addAttr(~0U, PA);<br>
> +  const AttrListPtr PALnew = PAL.addAttr(~0U, Attributes(PA));<br>
>   Func->setAttributes(PALnew);<br>
>  }<br>
><br>
>  void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) {<br>
>   Function *Func = unwrap<Function>(Fn);<br>
>   const AttrListPtr PAL = Func->getAttributes();<br>
> -  const AttrListPtr PALnew = PAL.removeAttr(~0U, PA);<br>
> +  const AttrListPtr PALnew = PAL.removeAttr(~0U, Attributes(PA));<br>
>   Func->setAttributes(PALnew);<br>
>  }<br>
><br>
> @@ -1365,7 +1366,7 @@<br>
>   Function *Func = unwrap<Function>(Fn);<br>
>   const AttrListPtr PAL = Func->getAttributes();<br>
>   Attributes attr = PAL.getFnAttributes();<br>
> -  return (LLVMAttribute)attr;<br>
> +  return (LLVMAttribute)attr.Raw();<br>
>  }<br>
><br>
>  /*--.. Operations on parameters ............................................--*/<br>
> @@ -1427,18 +1428,18 @@<br>
>  }<br>
><br>
>  void LLVMAddAttribute(LLVMValueRef Arg, LLVMAttribute PA) {<br>
> -  unwrap<Argument>(Arg)->addAttr(PA);<br>
> +  unwrap<Argument>(Arg)->addAttr(Attributes(PA));<br>
>  }<br>
><br>
>  void LLVMRemoveAttribute(LLVMValueRef Arg, LLVMAttribute PA) {<br>
> -  unwrap<Argument>(Arg)->removeAttr(PA);<br>
> +  unwrap<Argument>(Arg)->removeAttr(Attributes(PA));<br>
>  }<br>
><br>
>  LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg) {<br>
>   Argument *A = unwrap<Argument>(Arg);<br>
>   Attributes attr = A->getParent()->getAttributes().getParamAttributes(<br>
>     A->getArgNo()+1);<br>
> -  return (LLVMAttribute)attr;<br>
> +  return (LLVMAttribute)attr.Raw();<br>
>  }<br>
><br>
><br>
> @@ -1635,14 +1636,14 @@<br>
>                            LLVMAttribute PA) {<br>
>   CallSite Call = CallSite(unwrap<Instruction>(Instr));<br>
>   Call.setAttributes(<br>
> -    Call.getAttributes().addAttr(index, PA));<br>
> +    Call.getAttributes().addAttr(index, Attributes(PA)));<br>
>  }<br>
><br>
>  void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index,<br>
>                               LLVMAttribute PA) {<br>
>   CallSite Call = CallSite(unwrap<Instruction>(Instr));<br>
>   Call.setAttributes(<br>
> -    Call.getAttributes().removeAttr(index, PA));<br>
> +    Call.getAttributes().removeAttr(index, Attributes(PA)));<br>
>  }<br>
><br>
>  void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,<br>
><br>
> Modified: llvm/trunk/lib/VMCore/Verifier.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/VMCore/Verifier.cpp (original)<br>
> +++ llvm/trunk/lib/VMCore/Verifier.cpp Fri Jan 20 11:56:17 2012<br>
> @@ -547,7 +547,7 @@<br>
>   for (unsigned i = 0;<br>
>        i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {<br>
>     Attributes MutI = Attrs & Attribute::MutuallyIncompatible[i];<br>
> -    Assert1(!(MutI & (MutI - 1)), "Attributes " +<br>
> +    Assert1(MutI.isEmptyOrSingleton(), "Attributes " +<br>
>             Attribute::getAsString(MutI) + " are incompatible!", V);<br>
>   }<br>
><br>
> @@ -607,7 +607,7 @@<br>
>   for (unsigned i = 0;<br>
>        i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {<br>
>     Attributes MutI = FAttrs & Attribute::MutuallyIncompatible[i];<br>
> -    Assert1(!(MutI & (MutI - 1)), "Attributes " +<br>
> +    Assert1(MutI.isEmptyOrSingleton(), "Attributes " +<br>
>             Attribute::getAsString(MutI) + " are incompatible!", V);<br>
>   }<br>
>  }<br>
><br>
> Modified: llvm/trunk/utils/llvm.grm<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/llvm.grm?rev=148553&r1=148552&r2=148553&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/llvm.grm?rev=148553&r1=148552&r2=148553&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/utils/llvm.grm (original)<br>
> +++ llvm/trunk/utils/llvm.grm Fri Jan 20 11:56:17 2012<br>
> @@ -174,6 +174,7 @@<br>
>  | sspreq<br>
>  | returns_twice<br>
>  | nonlazybind<br>
> + | address_safety<br>
>  ;<br>
><br>
>  OptFuncAttrs  ::= + _ | OptFuncAttrs FuncAttr ;<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br>