LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 13676 - [Windows] Segmentation fault when returning a struct from a function or instance method
Summary: [Windows] Segmentation fault when returning a struct from a function or insta...
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: C++ (show other bugs)
Version: unspecified
Hardware: PC Windows NT
: P enhancement
Assignee: Timur Iskhodzhanov
URL:
Keywords:
Depends on: 15556
Blocks: 12477
  Show dependency tree
 
Reported: 2012-08-23 07:55 PDT by Timur Iskhodzhanov
Modified: 2013-04-17 09:56 PDT (History)
5 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Timur Iskhodzhanov 2012-08-23 07:55:09 PDT
As of r160851,

$ cat with_cl.cpp
struct S {
  int a, b;
};

class C {
 public:
  S foo();
};

S C::foo() {
  S ret;
  ret.a = 1;
  ret.b = 2;
  return ret;
}
///////////////////// EOF
$ cat with_clang.cpp
struct S {
  int a, b;
};

class C {
 public:
  S foo();
};

int main() {
  C c;
  S s = c.foo();
  if (s.a != 1)
    return 1;
  if (s.b != 2)
    return 2;
}
///////////////////// EOF
$ clang -Xclang -cxx-abi -Xclang microsoft -c with_clang.cpp && cl -nologo -c with_cl.cpp && link -nologo with_cl.obj with_clang.o

$ with_cl.exe
Segmentation fault
Comment 1 Eli Friedman 2012-08-24 21:35:31 PDT
Could you attach the assembly generated by MSVC?
Comment 2 Chandler Carruth 2012-08-27 13:54:52 PDT
(In reply to comment #1)
> Could you attach the assembly generated by MSVC?

Please don't attach output generated by the MSVC compiler to the public bug tracker unless you understand all of the implications of its EULA.

I don't think we need it for Timur to continue working on this.
Comment 3 Timur Iskhodzhanov 2012-08-27 14:16:56 PDT
> I don't think we need it for Timur to continue working on this.
FTR,
I'm *not* working on this at the moment.
This was found in SPEC 2006 tests on the povray benchmark.

Currently I'm prioritized to get Clang working on Chromium and I don't think the pattern described in this bug is widespread there due to our strict code style. I might be wrong though as we have a lot of third_party/ there.

So feel free to take over unless I explicitly take it myself :)
Comment 4 Chandler Carruth 2012-08-27 14:59:14 PDT
(In reply to comment #3)
> > I don't think we need it for Timur to continue working on this.
> FTR,
> I'm *not* working on this at the moment.
> This was found in SPEC 2006 tests on the povray benchmark.
> 
> Currently I'm prioritized to get Clang working on Chromium and I don't think
> the pattern described in this bug is widespread there due to our strict code
> style.

I'll wager you one beverage of your choice that you end up having to fix this for Chromium. ;]

Anyways, prioritize as is convenient for you, I just was pointing out that whomever chooses to dig into this can likely do so w/o someone posting asm.
Comment 5 Timur Iskhodzhanov 2012-09-20 08:28:59 PDT
> I'll wager you one beverage of your choice that you end up having to fix
> this for Chromium. ;]
I was wise enough not to make a bet with you ;)

Indeed, Chromium's FilePath::DirName returns a FilePath by value, it's a 32-byte structure => boom it crashes.

--
Some more info.

Actually it turns out the problem is not that the struct is "2 integers".
At least I observe the same crash regardless of the "S" size (tested 4,8,12,32).

A similar "returning a struct" scenario works fine for non-class functions or static class method.
The crash also happens if I explicitly mark the method as __cdecl so it's likely not unique to thiscall (default method CC).

Changing the subject accordingly.
Comment 6 Timur Iskhodzhanov 2012-10-02 08:54:29 PDT
Taking this.

After some investigation, there are at least three different problems here:
1) LLVM: "sret" is currently mishandled on Windows.
   The current version of lib/Target/X86/X86CallingConv.td puts SRet into EAX though it should push the address on stack

2) Clang problem #1:
   Returning a struct with non-trivial default constructor should imply "sret";
   Currently, only the presence of a copy constructor or destructor implies sret.

3) Clang problem #2: Handling of __cdecl instance methods - to be investigated later.

I have small patches for (1) and (2), but their current versions likely break the Itanium ABI.
I'll send a couple of e-mails to llvm-dev and cfe-dev for design suggestions soon;
as well as adding a test for (2).
Comment 7 Timur Iskhodzhanov 2013-04-17 09:22:35 PDT
A fix for everything I know except for __cdecl methods has been committed as r179681.
I'll file an issue for __cdecl soon.
Comment 8 Timur Iskhodzhanov 2013-04-17 09:24:43 PDT
(See also r178291, r178634)
Comment 9 Timur Iskhodzhanov 2013-04-17 09:56:03 PDT
Re: cdecl - see PR15768