Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

assert "Function return type does not match operand type of return inst!" when building ObjC code for arm #16370

Closed
nico opened this issue May 14, 2013 · 10 comments
Labels
bugzilla Issues migrated from bugzilla clang:codegen IR generation bugs: mangling, exceptions, etc.

Comments

@nico
Copy link
Contributor

nico commented May 14, 2013

Bugzilla Link 15998
Resolution FIXED
Resolved on Jun 18, 2013 17:42
Version unspecified
OS All
CC @lattner,@DougGregor,@efriedma-quic,@jayfoad,@zygoloid,@rjmccall

Extended Description

hummer:src thakis$ cat test.mm
template struct scoped_nsprotocol {
scoped_nsprotocol() {}
};

@​interface View
@​end
@​protocol protocol1
@​end
@​protocol protocol2
@​end
class Controller {
public:
Controller();
scoped_nsprotocol<View > p1;
scoped_nsprotocol<View > p2;
};
Controller::Controller() {}
hummer:src thakis$ third_party/llvm-build/Release+Asserts/bin/clang -c test.mm
hummer:src thakis$ third_party/llvm-build/Release+Asserts/bin/clang -c test.mm -arch arm
Function return type does not match operand type of return inst!
ret %struct.scoped_nsprotocol.0* %call
%struct.scoped_nsprotocolBroken module found, compilation aborted!
0 clang 0x00000001018315d8 llvm::sys::PrintStackTrace(__sFILE
) + 40
1 clang 0x0000000101831b44 SignalHandler(int) + 564
2 libsystem_c.dylib 0x00007fff87fa194a _sigtramp + 26
3 libsystem_c.dylib 0x0000000102840a00 _sigtramp + 2055860432
4 clang 0x00000001018318f6 abort + 22
5 clang 0x00000001017e865e (anonymous namespace)::Verifier::abortIfBroken() + 510
6 clang 0x00000001017e8316 (anonymous namespace)::Verifier::runOnFunction(llvm::Function&) + 1958
7 clang 0x00000001017cefdb llvm::FPPassManager::runOnFunction(llvm::Function&) + 347
8 clang 0x00000001017ce7fb llvm::FunctionPassManagerImpl::run(llvm::Function&) + 219
9 clang 0x00000001017ce6ce llvm::FunctionPassManager::run(llvm::Function&) + 94
10 clang 0x00000001001af264 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::Module*, clang::BackendAction, llvm::raw_ostream*) + 5460
11 clang 0x00000001002a0f28 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) + 600
12 clang 0x00000001002e4144 clang::ParseAST(clang::Sema&, bool, bool) + 516
13 clang 0x000000010029fe97 clang::CodeGenAction::ExecuteAction() + 215
14 clang 0x0000000100066f17 clang::FrontendAction::Execute() + 119
15 clang 0x000000010004223d clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 957
16 clang 0x0000000100009e5d clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 3693
17 clang 0x0000000100001081 cc1_main(char const**, char const**, char const*, void*) + 801
18 clang 0x0000000100007133 main + 6963
19 clang 0x0000000100000d34 start + 52
20 clang 0x000000000000003f start + 4294964031
Stack dump:
0. Program arguments: /Volumes/MacintoshHD2/src/chrome-git/src/third_party/llvm-build/Release+Asserts/bin/clang -cc1 -triple armv4t-apple-macosx10.8.0 -emit-obj -mrelax-all -disable-free -main-file-name test.mm -mrelocation-model pic -pic-level 2 -mdisable-fp-elim -masm-verbose -target-abi apcs-gnu -target-cpu arm7tdmi -msoft-float -mfloat-abi soft -target-feature +soft-float -target-feature +soft-float-abi -target-feature -neon -target-linker-version 136 -coverage-file /Users/thakis/src/chrome-git/src/test.o -resource-dir /Volumes/MacintoshHD2/src/chrome-git/src/third_party/llvm-build/Release+Asserts/bin/../lib/clang/3.3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk -fdeprecated-macro -fdebug-compilation-dir /Users/thakis/src/chrome-git/src -ferror-limit 19 -fmessage-length 271 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.8.0 -fobjc-default-synthesize-properties -fencode-extended-block-signature -fobjc-exceptions -fcxx-exceptions -fexceptions -fsjlj-exceptions -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -o test.o -x objective-c++ test.mm

  1. parser at end of file
  2. Per-function optimization
  3. Running pass 'Module Verifier' on function '@_ZN17scoped_nsprotocolI4ViewEC1Ev'
    clang: error: unable to execute command: Illegal instruction: 4
    clang: error: clang frontend command failed due to signal (use -v to see invocation)
    clang version 3.3 (trunk 179138)
    Target: arm-apple-darwin12.3.0

This works fine with Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn) (but maybe only because that's build without asserts?).

It is still an issue at today's head (r181805).

@nico
Copy link
Contributor Author

nico commented May 14, 2013

Jay touched this assert 2 years ago, maybe he knows how to find out which caller is doing something wrong.

@jayfoad
Copy link
Contributor

jayfoad commented May 15, 2013

The assertion fails because clang is generating this:

define linkonce_odr arm_aapcscc %struct.scoped_nsprotocol* @​_ZN17scoped_nsprotocolI4ViewEC1Ev(%struct.scoped_nsprotocol*) unnamed_addr #​0 align 2 {
entry:
%this.addr = alloca %struct.scoped_nsprotocol.0*, align 4
%this = bitcast %struct.scoped_nsprotocol* %0 to %struct.scoped_nsprotocol.0*
store %struct.scoped_nsprotocol.0* %this, %struct.scoped_nsprotocol.0** %this.addr, align 4
%this1 = load %struct.scoped_nsprotocol.0** %this.addr
%call = call arm_aapcscc %struct.scoped_nsprotocol.0* @​_ZN17scoped_nsprotocolI4ViewEC2Ev(%struct.scoped_nsprotocol.0* %this1)
ret %struct.scoped_nsprotocol.0* %call
}

The return type of the function is "%struct.scoped_nsprotocol*", but the ret instruction tries to return "%struct.scoped_nsprotocol.0*" (note the extra ".0").

This happens because clang tries to create two different structs, but gives them the same name; LLVM then auto-renames one of them by appending ".0".

I can see in the debugger that CodeGenTypes::ConvertRecordDecl is called on these two RecordDecls. Each call creates a different struct with the same name "struct.scoped_nsprotocol":

(gdb) call RD->dump()
ClassTemplateSpecializationDecl 0x4f64920 <test.mm:1:1, line:3:1> struct scoped_nsprotocol
|-TemplateArgument type 'View'
|-CXXRecordDecl 0x4f64b30 prev 0x4f64920 <line:1:25, col:32> struct scoped_nsprotocol
|-CXXConstructorDecl 0x4f64c00 line:2:3 scoped_nsprotocol 'void (void)'
-CXXConstructorDecl 0x4f7b270 <line:1:32> scoped_nsprotocol 'void (const struct scoped_nsprotocol<View<protocol1> > &)' inline -ParmVarDecl 0x4f7b3b0 col:32 'const struct scoped_nsprotocol<View > &'

(gdb) call RD->dump()
ClassTemplateSpecializationDecl 0x4f7ab20 <test.mm:1:1, line:3:1> struct scoped_nsprotocol
|-TemplateArgument type 'View'
|-CXXRecordDecl 0x4f7ad30 prev 0x4f7ab20 <line:1:25, col:32> struct scoped_nsprotocol
|-CXXConstructorDecl 0x4f7ae00 line:2:3 scoped_nsprotocol 'void (void)'
-CXXConstructorDecl 0x4f7b4a0 <line:1:32> scoped_nsprotocol 'void (const struct scoped_nsprotocol<View<protocol2> > &)' inline -ParmVarDecl 0x4f7b5e0 col:32 'const struct scoped_nsprotocol<View > &'

@nico
Copy link
Contributor Author

nico commented May 15, 2013

And this doesn't happen on x86 because constructors return void there?

Chris touched CodeGenTypes::ConvertRecordDecl() last (2011), maybe he knows if that function is doing the wrong thing or if the frontend is feeding it bad data.

@lattner
Copy link
Collaborator

lattner commented May 15, 2013

Sorry, I don't have any specific insight here anymore.

@nico
Copy link
Contributor Author

nico commented May 15, 2013

This has been broken since at least r138188, so removing the "Regression" bit from the bug title.

@nico
Copy link
Contributor Author

nico commented May 15, 2013

Jay: Hm, if I change the input to

template struct scoped_nsprotocol {
scoped_nsprotocol() {}
};
class Controller {
public:
Controller();
scoped_nsprotocol p1;
scoped_nsprotocol p2;
};
Controller::Controller() {}

…then clang also generates structs with the same name, but llvm's renaming pass doesn't get confused about them. So just having an identical name doesn't seem to trigger the problem?

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented May 23, 2013

The problem seems to be that we use the same mangled name for View and View but treat them as canonically different types. Note that neither "protocol1" nor "protocol2" appears within "_ZN17scoped_nsprotocolI4ViewEC2Ev"

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented May 23, 2013

As far as I can tell, you've fallen into a hole in the Objective-C++ ABI.

@nico
Copy link
Contributor Author

nico commented May 23, 2013

Ah, thanks!

Reminds me of http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110718/044168.html , so maybe something similar can be done here?

@efriedma-quic
Copy link
Collaborator

r184250.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 4, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla clang:codegen IR generation bugs: mangling, exceptions, etc.
Projects
None yet
Development

No branches or pull requests

4 participants