Author: gbiv Date: Thu Apr 13 18:47:08 2017 New Revision: 300283 URL: http://llvm.org/viewvc/llvm-project?rev=300283&view=rev Log: Fix PR31934: forming refs to functions with enable_if attrs.
Modified: cfe/trunk/lib/Sema/SemaInit.cpp cfe/trunk/test/SemaCXX/enable_if.cpp Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=300283&r1=300282&r2=300283&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Apr 13 18:47:08 2017 @@ -6684,6 +6684,19 @@ InitializationSequence::Perform(Sema &S, if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType)) return ExprError(); + // We don't check for e.g. function pointers here, since address + // availability checks should only occur when the function first decays + // into a pointer or reference. + if (CurInit.get()->getType()->isFunctionProtoType()) { + if (auto *DRE = dyn_cast<DeclRefExpr>(CurInit.get()->IgnoreParens())) { + if (auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) { + if (!S.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, + DRE->getLocStart())) + return ExprError(); + } + } + } + // Even though we didn't materialize a temporary, the binding may still // extend the lifetime of a temporary. This happens if we bind a reference // to the result of a cast to reference type. Modified: cfe/trunk/test/SemaCXX/enable_if.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/enable_if.cpp?rev=300283&r1=300282&r2=300283&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/enable_if.cpp (original) +++ cfe/trunk/test/SemaCXX/enable_if.cpp Thu Apr 13 18:47:08 2017 @@ -472,3 +472,30 @@ namespace instantiate_constexpr_in_enabl }; void g() { X<int>().f(); } } + +namespace PR31934 { +int foo(int a) __attribute__((enable_if(a, ""))); +int runFn(int (&)(int)); + +void run() { + { + int (&bar)(int) = foo; // expected-error{{cannot take address of function 'foo'}} + int baz = runFn(foo); // expected-error{{cannot take address of function 'foo'}} + } + + { + int (&bar)(int) = (foo); // expected-error{{cannot take address of function 'foo'}} + int baz = runFn((foo)); // expected-error{{cannot take address of function 'foo'}} + } + + { + int (&bar)(int) = static_cast<int (&)(int)>(foo); // expected-error{{cannot take address of function 'foo'}} + int baz = runFn(static_cast<int (&)(int)>(foo)); // expected-error{{cannot take address of function 'foo'}} + } + + { + int (&bar)(int) = static_cast<int (&)(int)>((foo)); // expected-error{{cannot take address of function 'foo'}} + int baz = runFn(static_cast<int (&)(int)>((foo))); // expected-error{{cannot take address of function 'foo'}} + } +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits