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

Richard Trieu rtrieu at google.com
Fri Jun 21 19:41:01 PDT 2013


As of r184616, Clang will work on function pointers that is returned from a
function.


On Thu, Jun 20, 2013 at 2:32 PM, Richard Trieu <rtrieu at google.com> wrote:

> 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/20130621/fb8ed847/attachment.html>


More information about the cfe-commits mailing list