This is an archive of the discontinued LLVM Phabricator instance.

[CodeGen][ObjC] zero-ext an i1 value to i8
ClosedPublic

Authored by ahatanak on May 18 2016, 6:08 PM.

Details

Summary

This patch fixes an assert that fires when there is a property that has attribute nonatomic and type _Atomic(_Bool). The assert fires when an i1 value is bitcast to i8 (which is the type ConvertType(propType) returns).

I have a couple of questions as I wasn't sure this was the right way to fix the assert.

  1. Is it legal to have attribute nonatomic on a property that has an atomic type? Should clang error out?
  2. Should the return type of the getter method be i1 or i8? I chose not to change the return type (which was i8), but I think there are cases where changing it to i1 might make more sense. For example, the following code currently doesn't compile because foo1 and the getter for "p" (which is the property of A in the test case) have different return types.
_Bool foo1() {
  A *a = [A new];
  return i.p;
}

rdar://problem/26322972

Diff Detail

Repository
rL LLVM

Event Timeline

ahatanak updated this revision to Diff 57718.May 18 2016, 6:08 PM
ahatanak retitled this revision from to [CodeGen][ObjC] zero-ext an i1 value to i8.
ahatanak updated this object.
ahatanak added a reviewer: rjmccall.
ahatanak added a subscriber: cfe-commits.

Also, it seems that there are bugs in the way clang handles functions whose return types are atomic. Clang asserts when compiling the following test case:

$ cat t1.c

_Atomic _Bool b1;

_Atomic _Bool foo1() {
  return b1;
}

$ clang -std=c11 -o - -S t1.c -emit-llvm

rjmccall edited edge metadata.May 18 2016, 8:38 PM

_Atomic is functionally a type qualifier and should be removed in Sema when computing the result type of the getter and the parameter type of the setter. That is, if the user declares a property of type _Atomic(_Bool), we should pretend that the property has type _Bool when creating the getter and setter.

_Atomic is functionally a type qualifier and should be removed in Sema when computing the result type of the getter and the parameter type of the setter. That is, if the user declares a property of type _Atomic(_Bool), we should pretend that the property has type _Bool when creating the getter and setter.

That sounds like a more principled way to fix the problem. We'll have to remove _Atomic from return types of normal functions too, not just objective-c getters and setters, because otherwise programs like this won't compile:

_Atomic(_Bool) foo1() {
  A *a = [A new];
  return a.p;
}

I've managed to remove _Atomic from the types of the return and parameter of getter and setter functions in my new patch.

I'm not sure how I should handle typedefs though. If I had the following typedef,

typedef _Atomic(_Bool) AtomicBool,

would it be OK to desugar the typedef and then remove _Atomic? I'm not sure this is always correct because dusugaring typedefs will remove the attributes attached to them that might be important too.

Top-level attributes shouldn't really be affecting the ABI or code-generation in any way, so desugaring should be fine.

ahatanak updated this revision to Diff 58144.May 23 2016, 1:29 PM
ahatanak edited edge metadata.

Rewrote the patch based on John's review comment.

Remove typedefs and _Atomic from the return and parameter types of getters and setters of objective-c properties.

rjmccall added inline comments.May 25 2016, 12:01 PM
include/clang/AST/Type.h
1084 ↗(On Diff #58144)

Please name this getAtomicUnqualifiedType() and have it promise to remove all qualifiers including _Atomic. It should not promise to remove type sugar.

lib/AST/Type.cpp
1282 ↗(On Diff #58144)

This should just be:

if (auto AT = getAs<AtomicType>()) {
  return AT->getValueType().getUnqualifiedType();
} else {
  return getUnqualifiedType();
}
lib/CodeGen/CGObjC.cpp
901 ↗(On Diff #58144)

The code around here uses lowercase identifiers, please be consistent.

1023 ↗(On Diff #58144)

I don't understand the purpose of doing two bitcasts here, so let's just drop this first one.

lib/Sema/SemaDeclObjC.cpp
4319 ↗(On Diff #58144)

Hmm. I'm not sure you should be doing this here; or at least, if we're going to do it, we should probably be doing it consistently in CheckFunctionReturnType.

4361 ↗(On Diff #58144)

Same thing. If the user wants to explicitly declare a parameter _Atomic, they can do so.

lib/Sema/SemaObjCProperty.cpp
1497 ↗(On Diff #58144)

This is incorrect. The property ivar type should definitely remain _Atomic if the property was declared that way.

2210 ↗(On Diff #58144)

Please pull this above the comment and give it its own comment, something like:

// The getter returns the declared property type with all qualifiers removed.
2282 ↗(On Diff #58144)

Same thing: please pull this above and give it its own comment.

ahatanak updated this revision to Diff 58495.May 25 2016, 1:49 PM

Address John's review comments.

ahatanak marked 7 inline comments as done.May 25 2016, 1:53 PM
ahatanak added inline comments.
lib/AST/Type.cpp
1282 ↗(On Diff #58495)

I added getTypePtr() because the code didn't compile.

lib/CodeGen/CGObjC.cpp
901 ↗(On Diff #58495)

I've only changed ivarSize. I can change the variable names defined below (RetTy and RetTySize) too if that is necesasry.

ahatanak marked 2 inline comments as done.May 25 2016, 1:57 PM

I reverted the changes I made in SemaDeclObjC.cpp as they weren't needed to pass the regression tests I added. clang still asserts when it compiles an objective-c method returning _Atomic and those changes will become necessary when I fix that later. Normal functions returning _Atomic doesn't compile either.

rjmccall added inline comments.May 25 2016, 2:03 PM
lib/AST/Type.cpp
1282 ↗(On Diff #58495)

Sure.

lib/CodeGen/CGObjC.cpp
901 ↗(On Diff #58495)

Please do.

lib/Sema/SemaObjCProperty.cpp
1497 ↗(On Diff #58495)

You know what, I'm sorry, I didn't look closely enough at the context. Please just rename PropertyIvarType to something like PropertyRValueType.

I reverted the changes I made in SemaDeclObjC.cpp as they weren't needed to pass the regression tests I added. clang still asserts when it compiles an objective-c method returning _Atomic and those changes will become necessary when I fix that later. Normal functions returning _Atomic doesn't compile either.

The C standard is poorly-written in this area, but I think it would be reasonable for CheckFunctionReturnType to just silently remove _Atomic. (You will not be able to just re-use your new method there; removing other qualifiers is not acceptable, I'm afraid.)

ahatanak updated this revision to Diff 58512.May 25 2016, 2:17 PM

Rename variables.

The C standard is poorly-written in this area, but I think it would be reasonable for CheckFunctionReturnType to just silently remove _Atomic. (You will not be able to just re-use your new method there; removing other qualifiers is not acceptable, I'm afraid.)

Do you mean I should fix those cases in this patch too?

The C standard is poorly-written in this area, but I think it would be reasonable for CheckFunctionReturnType to just silently remove _Atomic. (You will not be able to just re-use your new method there; removing other qualifiers is not acceptable, I'm afraid.)

Do you mean I should fix those cases in this patch too?

No, sorry, just pointing something out for your other patch.

One minor improvement to the API and LGTM.

include/clang/AST/Type.h
1084 ↗(On Diff #58512)

This doesn't need an ASTContext.

ahatanak updated this revision to Diff 58544.May 25 2016, 5:26 PM

Thanks for the review. I've removed parameter ASTContext that was unused.

This revision was automatically updated to reflect the committed changes.