Hi David,
Here is a test case which works now, but breaks in the Obj-C runtime
with your patch:
--
#include <objc/runtime.h>
@interface A -(void) im0; @end
SEL f0() {
SEL S[] = { @selector(im0) };
return S[0];
}
--
On Wed, Feb 3, 2010 at 3:58 PM, David Chisnall <[email protected]> wrote:
> On 3 Feb 2010, at 23:29, David Chisnall wrote:
>
>> Hi Daniel,
>>
>> How does this break the NeXT runtime? I ran the test suite and got no
>> failures, and I tested a few extra @selector() cases with -fnext-runtime and
>> got code that looked correct. If you can provide me with a test case that
>> demonstrates how this breaks the NeXT runtime then I'd be happy to fix it.
>>
>> The code generation code paths for the NeXT runtime should be exactly the
>> same before and after the patch and the only change in Sema produces the
>> warning conditionally, suppressing it when the NeXT runtime is used.
>
> Specifically, this is the only code modified in the Mac runtime:
>
>> + virtual llvm::Constant *GetConstantSelector(Selector Sel) {
>> + assert(0 && "Constant Selectors are not yet supported on the Mac
>> runtimes");
>> + return 0;
>> + }
>> + virtual llvm::Constant *GetConstantTypedSelector(
>> + const ObjCMethodDecl *Method) {
>> + return GetConstantSelector(Method->getSelector());
>> + }
>>
>
>
> This is only called in one place, in CGExprConstant:
>
>> + llvm::Constant *VisitObjCSelectorExpr(const ObjCSelectorExpr *E) {
>> + ObjCMethodDecl *OMD = E->getMethodDecl();
>> + if (OMD)
>> + return CGM.getObjCRuntime().GetConstantTypedSelector(OMD);
>> + else
>> + return CGM.getObjCRuntime().GetConstantSelector(E->getSelector());
>> + }
>> +
>
> This does change the behaviour on the Mac runtime. The change in this file
> cause it fails with an assert that CGObjCMac doesn't yet support this
> behaviour instead of 'can not codegen this constant expression'. This is now
> reached because of this change in AST/Expr.cpp:
>
>> + case ObjCSelectorExprClass:
>> return true;
>
> Which was incorrect before the change; @selector() expressions are constants
> and GCC treats them as such. The following will compile quite happily in GCC:
>
> static SEL foo = @selector(foo);
I see. This is not supported when compiling for the NeXT runtime, can
you update your patch to reflect this?
--
ddun...@giles:tmp$ cat t.m
#include <objc/runtime.h>
@interface A -(void) im0; @end
static SEL S = @selector(im0);
SEL f0() {
static SEL S = @selector(im0);
return S;
}
SEL f1() {
static SEL S[] = { @selector(im0) };
return S[0];
}
ddun...@giles:tmp$ gcc -m32 t.m
t.m:3: error: initializer element is not constant
t.m: In function 'f0':
t.m:5: error: initializer element is not constant
t.m: In function 'f1':
t.m:9: error: initializer element is not constant
t.m:9: error: (near initialization for 'S[0]')
ddun...@giles:tmp$ gcc -m64 t.m
t.m:3: error: initializer element is not constant
t.m: In function 'f0':
t.m:5: error: initializer element is not constant
t.m: In function 'f1':
t.m:9: error: initializer element is not constant
t.m:9: error: (near initialization for 'S[0]')
ddun...@giles:tmp$ clang -m32 t.m
t.m:3:16: error: initializer element is not a compile-time constant
static SEL S = @selector(im0);
^~~~~~~~~~~~~~
t.m:5:18: error: initializer element is not a compile-time constant
static SEL S = @selector(im0);
^~~~~~~~~~~~~~
t.m:9:20: error: initializer element is not a compile-time constant
static SEL S[] = { @selector(im0) };
^~~~~~~~~~~~~~~~~~
3 diagnostics generated.
ddun...@giles:tmp$ clang -m64 t.m
t.m:3:16: error: initializer element is not a compile-time constant
static SEL S = @selector(im0);
^~~~~~~~~~~~~~
t.m:5:18: error: initializer element is not a compile-time constant
static SEL S = @selector(im0);
^~~~~~~~~~~~~~
t.m:9:20: error: initializer element is not a compile-time constant
static SEL S[] = { @selector(im0) };
^~~~~~~~~~~~~~~~~~
3 diagnostics generated.
ddun...@giles:tmp$
--
> The only other change that touched Mac runtime code paths was this:
>
>> + ObjCMethodDecl *OMD = E->getMethodDecl();
>> + if (OMD)
>> + return CGM.getObjCRuntime().GetSelector(Builder, OMD);
>> + else
>> + return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector());
>
> This calls a method that was already present in the GCObjCMac (calling
> EmitSelector() with OMD->getSelector() as the argument, so this will generate
> exactly the same code for both code paths on the Mac runtime).
>
> The only other change was to add a ObjCMethodDecl to the ObjCSelectorExpr.
> This change has no semantic effect on the Mac runtime - indeed, the test for
> the Mac runtime here was added specifically because an earlier version of the
> patch did fail a test because a warning that the Mac runtime didn't expect
> was generated.
>
> So, I am at a loss to see where this broke the Mac runtime aside from causing
> it to fail in a different place when you try to compile (valid) code which
> uses an @selector() expression as a static initialiser. I'm sorry if it
> broke the Mac runtime, but I did test it with all of the tests in the current
> test suite (and got no unexpected failures) and with a few extra programs
> using -S -fnext-runtime -emit-llvm to see if it still generated the same code
> as before the patch.
Fair enough. Our test suite is very limited, this is an unfortunate reality.
> 'Substantially breaks working code' is possibly the least useful bug report
> that I have ever read. I did everything in my power to ensure that this did
> not affect the Mac runtime, but if it did then I would appreciate it if you
> would provide me with some hints as to how it broke the Mac runtime, rather
> than just asserting that it did.
Sorry, your commit message made it sound like you were already aware
of the issue but had committed it anyway (hence my response). I
understand now you thought it was just enabling code that already
didn't work. I still think that:
(a) it definitely should come with a test case,
(b) it would have made sense to send as a PATCH, even just as a
heads up since it *could* impact the NeXT runtime and you don't have
the ability to test it.
- Daniel
>
> David
>
> -- Sent from my Apple II
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits