[cfe-dev] handle __attribute__((deprecated))

Ted Kremenek kremenek at apple.com
Fri Mar 7 10:46:52 PST 2008


Thanks Nuno!  Looks great.  Applied:

http://llvm.org/viewvc/llvm-project?rev=48011&view=rev

On Mar 7, 2008, at 10:23 AM, Nuno Lopes wrote:

> Hi,
>
> So I've tried to fullfill all comments. Additionally I also provide  
> a test for most corner-cases.
> The C++ part is still not handled, but it should be much easier now.
>
> Nuno
>
>
> ----- Original Message ----- From: "Ted Kremenek" <kremenek at apple.com>
> To: "Nuno Lopes" <nunoplopes at sapo.pt>
> Cc: "cfe-dev" <cfe-dev at cs.uiuc.edu>
> Sent: Monday, March 03, 2008 5:47 PM
> Subject: Re: [cfe-dev] handle __attribute__((deprecated))
>
>
>>
>> On Mar 1, 2008, at 12:28 AM, Chris Lattner wrote:
>>
>>> Should this emit a diagnostic if it's not a function?  Ted, can you
>>> please review the rest of the 'HandleFormatAttribute' method?
>>
>> Hi Nuno,
>>
>> I've reviewed the version of HandleFormatAttribute that Chris
>> committed to the clang tree from your latest patch.  Thanks again for
>> submitting this patch.  It's a great contribution.  I have a few
>> comments:
>>
>>
>>  // FIXME: in C++ the implicit 'this' function parameter also counts.
>>  // the index must start in 1 and the limit is numargs+1
>>  unsigned NumArgs = Fn->getNumParams()+1; // +1 for ...
>>
>>
>> This looks incorrect for all code except non-static C++ methods, of
>> which we do not currently handle.  The code after this frequently
>> checks against NumArgs, which will be incorrect (off-by-one).  Also,
>> I'm not certain how we are actually going to handle declarations for
>> class members, but chances are we are not going to use FunctionDecls.
>> I would just remove the increment for now, and leave the FIXME.  When
>> I first looked at this code I was also a little confused; I thought
>> you were trying to offset for a deficiency in the AST, rather than  
>> the
>> fact that this is a game that the format attribute plays in GCC  
>> (i.e.,
>> offsetting for the implicit "this" pointer):
>>
>>  "Since non-static C++ methods have an implicit this argument, the
>> arguments of such methods should be counted from two, not one..."
>>
>> Make a comment that this is is mirroring GCC behavior when it comes  
>> to
>> C++ non-static methods and the format attribute.  It also seems that
>> offsets to the base index would have to be handled as well.  I would
>> just punt on this for now until we have Decls for C++ methods in
>> place.  I'm a little concerned about doing this right for C++ non-
>> static methods; having little fudges like these to indices and ranges
>> is a great source for off-by-one and buffer overflow errors if not  
>> all
>> of the code obeys the rule.  This behavior just seems like a GCC
>> kludge, with the ASTs being tied to closely to the implementation of
>> how methods are code generated (thus forcing the attribute
>> specification itself to be broken); in reality, the "this" pointer
>> would never be used as a format string, so we probably should just
>> pretend that it isn't there when processing the format argument
>> indices.  This means that in the code below your original increment  
>> of
>> NumArgs that we should instead *decrement* the parsed indices when
>> handling C++ non-static methods.  That way, the FormatAttr object
>> always stores the canonicalized indices for the *explicit* function
>> arguments (again, ignoring the "this" argument).
>>
>> More comments:
>>
>>  Expr *IdxExpr = static_cast<Expr *>(rawAttr->getArg(0));
>>  llvm::APSInt Idx(32);
>>  if (!IdxExpr->isIntegerConstantExpr(Idx, Context)) {
>>    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int,
>>           "format", std::string("2"), IdxExpr->getSourceRange());
>>    return;
>>  }
>>
>>
>> Please do not hardcode "32" or the signedness of Idx, both which  
>> could
>> be target specific.  Please query these using
>> Context::getTypeSize(IdxExpr) and IdxExpr->getType()-
>> isUnsignedIntegerType().
>>
>> For the following block, please add a big comment indicating what it
>> is trying to do:
>>
>>
>>  Expr *IdxExpr = static_cast<Expr *>(rawAttr->getArg(0));
>>  llvm::APSInt Idx(32);
>>  if (!IdxExpr->isIntegerConstantExpr(Idx, Context)) {
>>    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int,
>>           "format", std::string("2"), IdxExpr->getSourceRange());
>>    return;
>>  }
>>
>>  if (Idx.getZExtValue() < 1 || Idx.getZExtValue() > NumArgs) {
>>    Diag(rawAttr->getLoc(),  
>> diag::err_attribute_argument_out_of_bounds,
>>           "format", std::string("2"), IdxExpr->getSourceRange());
>>    return;
>>  }
>>
>>  Expr *FirstArgExpr = static_cast<Expr *>(rawAttr->getArg(1));
>>  llvm::APSInt FirstArg(32);
>>  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, Context)) {
>>    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int,
>>           "format", std::string("3"), FirstArgExpr- 
>> >getSourceRange());
>>    return;
>>  }
>>
>>  if (FormatLen == 8 && !memcmp(Format, "strftime", 8)) {
>>    if (FirstArg.getZExtValue() != 0) {
>>      Diag(rawAttr->getLoc(),
>> diag::err_format_strftime_third_parameter,
>>             FirstArgExpr->getSourceRange());
>>      return;
>>    }
>>  } else if (FirstArg.getZExtValue() > NumArgs) {
>>    Diag(rawAttr->getLoc(),  
>> diag::err_attribute_argument_out_of_bounds,
>>           "format", std::string("3"), FirstArgExpr- 
>> >getSourceRange());
>>    return;
>>  }
>>
>>
>> As far as comments are concerned, it would be great to see a citation
>> link to the appropriate references.  For example, the following link
>> provides GCC's documentation on format argument attributes:
>>
>> http://gcc.gnu.org/onlinedocs/gcc-4.2.3/gcc/Function-Attributes.html#index-g_t_0040code_007bformat_007d-function-attribute-1880
>>
>> Adding this link in a comment would be helpful so that people know
>> what this code is trying to implement.  This mirrors documentation
>> through the rest of clang where we try to cite either the C standard
>> or the appropriate reference.    Also, please add comments above
>> checks like "if (FirstArg.getZExtValue() != 0)" where the argument is
>> not suppose to be zero and *why*.
>>
>> There is no harm in adding comments that document behavior; for
>> example, before seeing this code I did not know that the format
>> attribute supported the __strftime__ and __strfmon__ archetypes.  I
>> don't think GCC always supported these archetypes, so adding some
>> comments saying what functionality this adds to the format attribute
>> would be incredibly useful to other people browsing this code (which
>> is one of the goals of clang).
>>
>> Overall, this patch looks very good, and like your previous patches,
>> it's a great contribution to clang.
>>
>> Ted
> <clang_format_attr.txt>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20080307/c5fbd598/attachment.html>


More information about the cfe-dev mailing list