diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2016-11-19 00:13:03 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2016-11-19 00:13:03 +0000 |
commit | f7d563c76c40acc361417ec1bdef6f15739516e4 (patch) | |
tree | 3eda79eca38a6ec8a17bedae6c9ad00fc64652d2 /clang | |
parent | eb4a0cb16b74f6b973c11bd0b371f387853e48fc (diff) | |
download | bcm5719-llvm-f7d563c76c40acc361417ec1bdef6f15739516e4.tar.gz bcm5719-llvm-f7d563c76c40acc361417ec1bdef6f15739516e4.zip |
[Sema] Don't allow applying address-of operator to a call to a function
with __unknown_anytype return type.
When the following code is compiled, Sema infers that the type of
__unknown_anytype is double:
extern __unknown_anytype func();
double *d = (double*)&func();
This triggers an assert in CodeGenFunction::EmitCallExprLValue because
it doesn't expect to see a call to a function with a non-reference
scalar return type.
This commit prevents the assert by making VisitUnaryAddrOf error out if
the address-of operator is applied to a call to a function with
__unknown_anytype return type.
rdar://problem/20287610
Differential revision: https://reviews.llvm.org/D26808
llvm-svn: 287410
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 7 | ||||
-rw-r--r-- | clang/test/SemaCXX/unknown-anytype.cpp | 12 |
3 files changed, 22 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 316cbe2e7da..0b459110a83 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8031,6 +8031,9 @@ def err_unsupported_unknown_any_call : Error< 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< diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index fae8bf0f548..9d0d55e6876 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -14774,6 +14774,13 @@ namespace { << 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); diff --git a/clang/test/SemaCXX/unknown-anytype.cpp b/clang/test/SemaCXX/unknown-anytype.cpp index 95ad0409340..78a01ba2d35 100644 --- a/clang/test/SemaCXX/unknown-anytype.cpp +++ b/clang/test/SemaCXX/unknown-anytype.cpp @@ -56,3 +56,15 @@ namespace test5 { (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; + } + +} |