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.
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.
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 210556)
+++ 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 210556)
+++ test/CodeGenCXX/throw-expressions.cpp (working copy)
@@ -80,3 +80,35 @@
// 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
+
+const 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: ret i32*
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits