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 <[email protected]> wrote: > On Thu, Jun 20, 2013 at 2:18 PM, Eli Friedman <[email protected]>wrote: > >> On Thu, Jun 20, 2013 at 2:03 PM, Richard Trieu <[email protected]> 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. >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
