ahatanak created this revision. ahatanak added reviewers: doug.gregor, spyffe. ahatanak added a subscriber: cfe-commits.
This patch fixes an assert in CodeGenFunction::EmitCallExprLValue that is triggered when the CallExpr's return type is not a reference type: assert(E->getCallReturnType(getContext())->isReferenceType() && "Can't have a scalar return unless the return type is a " "reference type!"); Alternatively, since it's legal to apply the address-of operator to a reference return, we can change the function return type to be a reference (in the test case, that would be double&) in RebuildUnknownAnyExpr::VisitUnaryAddrOf when compiling for C++ (but not when compiling for C). https://reviews.llvm.org/D26808 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/SemaCXX/unknown-anytype.cpp Index: test/SemaCXX/unknown-anytype.cpp =================================================================== --- test/SemaCXX/unknown-anytype.cpp +++ test/SemaCXX/unknown-anytype.cpp @@ -56,3 +56,15 @@ (X<int>)test0(); // expected-error{{implicit instantiation of undefined template 'test5::X<int>'}} } } + +namespace test6 { + extern __unknown_anytype func(); + extern __unknown_anytype var; + double *d; + + void test() { + d = (double*)&func(); // expected-error{{address-of operator cannot be applied to a call to a function with unknown return type}} + d = (double*)&var; + } + +} Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -14773,6 +14773,13 @@ << E->getSourceRange(); return ExprError(); } + + if (isa<CallExpr>(E->getSubExpr())) { + S.Diag(E->getOperatorLoc(), diag::err_unknown_any_addrof_call) + << E->getSourceRange(); + return ExprError(); + } + assert(E->getValueKind() == VK_RValue); assert(E->getObjectKind() == OK_Ordinary); E->setType(DestType); Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8017,6 +8017,9 @@ def err_unknown_any_addrof : Error< "the address of a declaration with unknown type " "can only be cast to a pointer type">; +def err_unknown_any_addrof_call : Error< + "address-of operator cannot be applied to a call to a function with " + "unknown return type">; def err_unknown_any_var_function_type : Error< "variable %0 with unknown type cannot be given a function type">; def err_unknown_any_function : Error<
Index: test/SemaCXX/unknown-anytype.cpp =================================================================== --- test/SemaCXX/unknown-anytype.cpp +++ test/SemaCXX/unknown-anytype.cpp @@ -56,3 +56,15 @@ (X<int>)test0(); // expected-error{{implicit instantiation of undefined template 'test5::X<int>'}} } } + +namespace test6 { + extern __unknown_anytype func(); + extern __unknown_anytype var; + double *d; + + void test() { + d = (double*)&func(); // expected-error{{address-of operator cannot be applied to a call to a function with unknown return type}} + d = (double*)&var; + } + +} Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -14773,6 +14773,13 @@ << E->getSourceRange(); return ExprError(); } + + if (isa<CallExpr>(E->getSubExpr())) { + S.Diag(E->getOperatorLoc(), diag::err_unknown_any_addrof_call) + << E->getSourceRange(); + return ExprError(); + } + assert(E->getValueKind() == VK_RValue); assert(E->getObjectKind() == OK_Ordinary); E->setType(DestType); Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8017,6 +8017,9 @@ def err_unknown_any_addrof : Error< "the address of a declaration with unknown type " "can only be cast to a pointer type">; +def err_unknown_any_addrof_call : Error< + "address-of operator cannot be applied to a call to a function with " + "unknown return type">; def err_unknown_any_var_function_type : Error< "variable %0 with unknown type cannot be given a function type">; def err_unknown_any_function : Error<
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits