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