Gentle ping..
I updated the patch to target latest the svn revision and added an regexpr
to check that "val" is really returned.
Thank you



On Wed, Jun 11, 2014 at 11:18 PM, Marius Wachtler <[email protected]>
wrote:

> Sorry for all the spam...
> I attached the wrong patch file.
>
>
>
> On Wed, Jun 11, 2014 at 11:16 PM, Marius Wachtler <[email protected]>
> wrote:
>
>> Thanks for your expertise.
>> Attached you can find an updated patch where I removed the const and made
>> the FileCheck a little bit more specific.
>>
>>
>>
>> On Wed, Jun 11, 2014 at 10:55 PM, Richard Smith <[email protected]>
>> wrote:
>>
>>> On Wed, Jun 11, 2014 at 1:25 PM, Marius Wachtler <[email protected]>
>>> wrote:
>>>
>>>> Hi
>>>>
>>>> I added a testcase for the function you mention but I also added const
>>>> to the return type because otherwise gcc won't compile it ("error: invalid
>>>> initialization of non-const reference of type ‘int&’ from an rvalue of type
>>>> ‘int’") - clang compiles both.
>>>>
>>>
>>> GCC doesn't implement one of the relevant DRs; you don't need to make
>>> the testcase work with it.
>>>
>>> The generated code from clang for the function looks correct and works
>>>> as I would expect it.
>>>> Compiling it with g++ 4.8.2 and -O2 will instead produce and object
>>>> which will return an address to a temporary in the function and not a
>>>> reference to the global val.
>>>>
>>>> I'm not sure if clangs behavior is correct or if it should also only
>>>> accept a const reference? If the error is somewhere else I would appreciate
>>>> some guidance to where to look around and what the expected behavior is.
>>>>
>>>
>>> See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1550;
>>> Clang's behavior is right, this is just a bug with IR generation.
>>>
>>> The C++11 non final standard I have says (5.16-2):
>>>> "If either the second or the third operand has type (possibly
>>>> cv-qualified) void, then the lvalue-to-rvalue (4.1), array-to-pointer (4.2),
>>>> and function-to-pointer (4.3) standard conversions are performed on the
>>>> second and third operands, and one of the following shall hold:
>>>> — The second or the third operand (but not both) is a throw-expression
>>>> (15.1); the result is of the type
>>>> of the other and is a prvalue.
>>>> — Both the second and the third operands have type void; the result is
>>>> of type void and is a prvalue. [ Note: This includes the case where both
>>>> operands are throw-expressions. — end note ]
>>>> "
>>>> So this means gcc is correct?
>>>>
>>>> Thank you very much
>>>> - Marius
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On Wed, Jun 11, 2014 at 1:05 AM, Richard Smith <[email protected]>
>>>> wrote:
>>>>
>>>>> Please also include a test that the produced lvalue actually has the
>>>>> right value. Something like:
>>>>>
>>>>> int &test7(bool cond) {
>>>>>   return cond ? throw 1 : val;
>>>>> }
>>>>>
>>>>> ... and check that the value returned is @_Z3val
>>>>>
>>>>> On Tue, Jun 10, 2014 at 3:01 PM, Marius Wachtler <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> Hi
>>>>>> Attached you can find an updates patch.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Tue, Jun 10, 2014 at 11:50 PM, David Majnemer <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> +
>>>>>>>> +  case Expr::CXXThrowExprClass: {
>>>>>>>> +    const auto* throwExpr = cast<CXXThrowExpr>(E);
>>>>>>>>
>>>>>>>
>>>>>>> Please stick the star on the RHS. Also, it is customary in LLVM and
>>>>>>> clang to spell it like "ThrowExpr"
>>>>>>>
>>>>>>>
>>>>>>>> +    EmitCXXThrowExpr(throwExpr);
>>>>>>>> +    const QualType subExprType =
>>>>>>>> throwExpr->getSubExpr()->getType();
>>>>>>>>
>>>>>>>
>>>>>>> Likewise for "subExprType"
>>>>>>>
>>>>>>> +    llvm::Type *Ty =
>>>>>>>> llvm::PointerType::getUnqual(ConvertType(subExprType));
>>>>>>>> +    return MakeAddrLValue(llvm::UndefValue::get(Ty), subExprType);
>>>>>>>>    }
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Tue, Jun 10, 2014 at 5:19 PM, Marius Wachtler <[email protected]
>>>>>>> > wrote:
>>>>>>>
>>>>>>>> Hello
>>>>>>>>
>>>>>>>> Attached you can find my first clang patch which should implement
>>>>>>>> "cond ? throw 1 : val".
>>>>>>>>
>>>>>>>> Without this patch I get: "cannot compile this l-value expression
>>>>>>>> yet"
>>>>>>>>
>>>>>>>> As this is my first time looking under the hood of clang I'm not
>>>>>>>> sure if this is the right approach. I'm Looking forward to your 
>>>>>>>> feedback.
>>>>>>>>
>>>>>>>> - Marius Wachtler
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> cfe-commits mailing list
>>>>>>>> [email protected]
>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> cfe-commits mailing list
>>>>>> [email protected]
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp	(revision 211031)
+++ lib/CodeGen/CGExpr.cpp	(working copy)
@@ -874,7 +874,16 @@
 
   case Expr::MaterializeTemporaryExprClass:
     return EmitMaterializeTemporaryExpr(cast<MaterializeTemporaryExpr>(E));
+
+  case Expr::CXXThrowExprClass: {
+    const auto *ThrowExpr = cast<CXXThrowExpr>(E);
+    EmitCXXThrowExpr(ThrowExpr);
+    const QualType SubExprType = ThrowExpr->getSubExpr()->getType();
+    llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(SubExprType));
+    return MakeAddrLValue(llvm::UndefValue::get(Ty), SubExprType);
   }
+
+  }
 }
 
 /// Given an object of the given canonical type, can we safely copy a
Index: test/CodeGenCXX/throw-expressions.cpp
===================================================================
--- test/CodeGenCXX/throw-expressions.cpp	(revision 211031)
+++ test/CodeGenCXX/throw-expressions.cpp	(working copy)
@@ -80,3 +80,36 @@
   // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN6DR15601AD1Ev {{.*}} @_ZGRN6DR15601rE
   // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev
 }
+
+void test7(bool cond) {
+  cond ? throw 1 : val;
+}
+// CHECK-LABEL: define void @_Z5test7b(
+// CHECK: br i1
+//
+// x.true:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// x.false:
+// CHECK: br label
+//
+// end:
+// CHECK: ret void
+
+int &test8(bool cond) {
+  return cond ? throw 1 : val;
+}
+// CHECK-LABEL: define nonnull i32* @_Z5test8b(
+// CHECK: br i1
+//
+// x.true:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// x.false:
+// CHECK: br label
+//
+// end:
+// CHECK: [[VAL:%[a-z0-9]+]] {{.*}}@val
+// CHECK-NEXT: ret i32* [[VAL]]
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to