<div dir="ltr"><div>Thanks for the clarifications for cases #2 and #3.</div><div> </div><div>For #1, you are right: there's an ImplicitCastExpr wrapping the StringLiteral in the AST. I think this approach is cleaner than casting in #2 and #3, so using what you suggested works like a charm:</div>
<div> </div><div>const Expr *arg = (CE->getArg(0))->IgnoreParenImpCasts();</div><div> </div><div>Thanks a lot!</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-05-01 18:12 GMT+02:00 Jordan Rose <span dir="ltr"><<a href="mailto:jordan_rose@apple.com" target="_blank">jordan_rose@apple.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The analyzer traffics in const Stmt * and const Expr * everywhere, so your temporary variable for #2 and #3 should be "const StringLiteral *SL" (or just "auto *SL" now that we're using C++11).<br>

<br>
The probable reason why this doesn't work is because there's probably an ImplicitCastExpr wrapping the StringLiteral, handling the decay from char[N] to char* (or const char *, or whatever). Depending on what you want to do, you may want to use Expr::IgnoreParenImpCasts to "look through" these kinds of filters.<br>

<br>
Jordan<br>
<br>
<br>
On May 1, 2014, at 4:31 , Aitor San Juan <<a href="mailto:aitor.sj@opendeusto.es">aitor.sj@opendeusto.es</a>> wrote:<br>
<br>
> Hello,<br>
><br>
> In a checker I want to test whether an argument to a function call is a String literal, but I'm a bit stuck. Could anybody shed a bit of light on this?<br>
><br>
> 1. This way seems to not work (although no compile-time error), but I don't understand why:<br>
><br>
> const Expr *arg = CE->getArg(0); // CE is a CallExpr<br>
> if ((arg != NULL) && (clang::isa<clang::StringLiteral>(arg))){<br>
> ...<br>
><br>
> 2. The following does not compile:<br>
><br>
> const Expr *arg = CE->getArg(0); // CE is a CallExpr<br>
> if (StringLiteral *SL = dyn_cast<StringLiteral>(arg)) {<br>
><br>
> invalid conversion from ‘llvm::cast_retty<clang::StringLiteral, const clang::Expr*>::ret_type {aka const clang::StringLiteral*}’ to ‘clang::StringLiteral*’ [-fpermissive]<br>
>     if (StringLiteral *SL = dyn_cast<StringLiteral>(arg)) {<br>
>                                                                            ^<br>
> 3. The following does not compile, however there's a non-const getArg() method:<br>
><br>
> Expr *arg = CE->getArg(0); // CE is a CallExpr<br>
> if (StringLiteral *SL = dyn_cast<StringLiteral>(arg)) {<br>
><br>
> error: invalid conversion from ‘const clang::Expr*’ to ‘clang::Expr*’ [-fpermissive]<br>
>     Expr *arg = CE->getArg(0);<br>
>                             ^<br>
><br>
> _______________________________________________<br>
> cfe-dev mailing list<br>
> <a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
<br>
</blockquote></div><br></div>