r184470 - Extend -Wnon-pod-varargs to check calls made from function pointers.

Richard Trieu rtrieu at google.com
Thu Jun 20 14:32:14 PDT 2013


On Thu, Jun 20, 2013 at 2:18 PM, Eli Friedman <eli.friedman at gmail.com>wrote:

> On Thu, Jun 20, 2013 at 2:03 PM, Richard Trieu <rtrieu at google.com> wrote:
>
>> Author: rtrieu
>> Date: Thu Jun 20 16:03:13 2013
>> New Revision: 184470
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=184470&view=rev
>> Log:
>> Extend -Wnon-pod-varargs to check calls made from function pointers.
>>
>> Modified:
>>     cfe/trunk/include/clang/Sema/Sema.h
>>     cfe/trunk/lib/Sema/SemaChecking.cpp
>>     cfe/trunk/lib/Sema/SemaExpr.cpp
>>     cfe/trunk/test/SemaCXX/vararg-non-pod.cpp
>>
>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=184470&r1=184469&r2=184470&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>> +++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 20 16:03:13 2013
>> @@ -7461,8 +7461,8 @@ private:
>>                           const FunctionProtoType *Proto);
>>    bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc,
>>                             ArrayRef<const Expr *> Args);
>> -  bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall,
>> -                      const FunctionProtoType *Proto);
>> +  bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,
>> +                        const FunctionProtoType *Proto);
>>    void CheckConstructorCall(FunctionDecl *FDecl,
>>                              ArrayRef<const Expr *> Args,
>>                              const FunctionProtoType *Proto,
>>
>> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=184470&r1=184469&r2=184470&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Thu Jun 20 16:03:13 2013
>> @@ -597,18 +597,24 @@ bool Sema::CheckObjCMethodCall(ObjCMetho
>>    return false;
>>  }
>>
>> -bool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall,
>> -                          const FunctionProtoType *Proto) {
>> +bool Sema::CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,
>> +                            const FunctionProtoType *Proto) {
>>    const VarDecl *V = dyn_cast<VarDecl>(NDecl);
>>    if (!V)
>>      return false;
>>
>>    QualType Ty = V->getType();
>> -  if (!Ty->isBlockPointerType())
>> +  if (!Ty->isBlockPointerType() && !Ty->isFunctionPointerType())
>>      return false;
>>
>> -  VariadicCallType CallType =
>> -      Proto && Proto->isVariadic() ? VariadicBlock :
>> VariadicDoesNotApply ;
>> +  VariadicCallType CallType;
>> +  if (!Proto) {
>> +    CallType = VariadicDoesNotApply;
>> +  } else if (Ty->isBlockPointerType()) {
>> +    CallType = VariadicBlock;
>> +  } else { // Ty->isFunctionPointerType()
>> +    CallType = VariadicFunction;
>> +  }
>>    unsigned NumProtoArgs = Proto ? Proto->getNumArgs() : 0;
>>
>>    checkCall(NDecl,
>>
>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=184470&r1=184469&r2=184470&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun 20 16:03:13 2013
>> @@ -4464,7 +4464,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, Na
>>      if (BuiltinID)
>>        return CheckBuiltinFunctionCall(BuiltinID, TheCall);
>>    } else if (NDecl) {
>> -    if (CheckBlockCall(NDecl, TheCall, Proto))
>> +    if (CheckPointerCall(NDecl, TheCall, Proto))
>>        return ExprError();
>>    }
>>
>
> What if someone does e.g. (FuncReturningVarargsFuncPtr())(a,b,c)?
>
> -Eli
>
>
$ cat PR16353.cc
struct Foo {
  Foo() {}
  Foo(const Foo&) {}
};

void f(...);

typedef void (*vararg_ptr)(...);

vararg_ptr g();

void h() {
  Foo foo;

  vararg_ptr ptr = f;
  f(foo);
  ptr(foo);
  (g())(foo);
}
$ clang -fsyntax-only -Wall PR16353.cc
PR16353.cc:26:5: error: cannot pass object of non-POD type 'Foo' through
variadic function; call will abort at runtime [-Wnon-pod-varargs]
  f(foo);
    ^
PR16353.cc:27:7: error: cannot pass object of non-POD type 'Foo' through
variadic function; call will abort at runtime [-Wnon-pod-varargs]
  ptr(foo);
      ^
2 errors generated.
$ gcc -fsyntax-only -Wall PR16353.cc
PR16353.cc: In function ‘void h()’:
PR16353.cc:26:8: error: cannot pass objects of non-trivially-copyable type
‘struct Foo’ through ‘...’
PR16353.cc:27:10: error: cannot pass objects of non-trivially-copyable type
‘struct Foo’ through ‘...’
PR16353.cc:28:12: error: cannot pass objects of non-trivially-copyable type
‘struct Foo’ through ‘...’

Looks like Clang doesn't detect it.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130620/2e68ef39/attachment.html>


More information about the cfe-commits mailing list