[LLVMbugs] [Bug 131] [llvm-gcc] ?: operator as lvalue not implemented
bugzilla-daemon at zion.cs.uiuc.edu
bugzilla-daemon at zion.cs.uiuc.edu
Tue Nov 18 15:47:45 PST 2003
http://llvm.cs.uiuc.edu/bugs/show_bug.cgi?id=131
sabre at nondot.org changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Keywords| |compile-fail
OS/Version|Linux |All
Platform|PC |All
Resolution| |FIXED
Summary|[llvm-gcc] Funky struct |[llvm-gcc] ?: operator as
|casting: "tree not supported|lvalue not implemented
|by llvm" |
Target Milestone|--- |1.1
Version|trunk |1.0
------- Additional Comments From sabre at nondot.org 2003-11-18 17:47 -------
Fixed. I *LOVE* GCC extensions!
Testcase here: test/Regression/CFrontend/2003-11-18-CondExprLValue.c
Patch here:
$ diff -u llvm-expand.c~ llvm-expand.c
--- llvm-expand.c~ 2003-11-18 15:11:50.000000000 -0600
+++ llvm-expand.c 2003-11-18 17:44:00.000000000 -0600
@@ -4825,6 +4825,66 @@
Result = D2V(make_temporary_alloca(Fn, ElTy));
llvm_expand_expr(Fn, exp, Result);
break;
+
+ case COND_EXPR: { /* ?: expression */
+ /* FIXME: This does not correctly conditionalize CLEANUP expressions because
+ no scopes are created!!! */
+
+ /* Allocate a new temporary to hold the result of the expression */
+ llvm_basicblock *TrueBlock = llvm_basicblock_new("cond_true");
+ llvm_basicblock *FalseBlock = llvm_basicblock_new("cond_false");
+ llvm_basicblock *ContinueBlock = llvm_basicblock_new("cond_continue");
+
+ /* Figure out a place to store the result across blocks. */
+ llvm_value *ResultLoc = D2V(make_temporary_alloca(Fn, Ty));
+
+ /* Expand condition and branch */
+ llvm_value *Cond = llvm_expand_expr(Fn, TREE_OPERAND(exp, 0), 0);
+ Cond = cast_if_type_not_equal(Fn, Cond, BoolTy);
+ append_inst(Fn, create_cond_branch(Cond, TrueBlock, FalseBlock));
+
+ /* Add the true block as the fall through */
+ llvm_ilist_push_back(llvm_basicblock, Fn->BasicBlocks, TrueBlock);
+
+ /* One branch of the cond can be void, if it never returns. For
+ example A ? throw : E */
+ if (TREE_TYPE(TREE_OPERAND(exp, 1)) != void_type_node) {
+ unsigned BStart = 0, BSize = 0;
+ llvm_value *Val = llvm_expand_lvalue_expr(Fn, TREE_OPERAND(exp, 1),
+ &BStart, &BSize);
+ assert(BStart == 0 && BSize == 0 &&
+ "Cannot handle lvalue bitfields in condexpr yet!");
+ append_inst(Fn, create_store_inst(Val, ResultLoc, 0));
+ } else {
+ llvm_expand_expr(Fn, TREE_OPERAND (exp, 1), 0);
+ }
+
+ /* Branch to the mainline computation */
+ append_inst(Fn, create_uncond_branch(ContinueBlock));
+
+ /* Add the false block next */
+ llvm_ilist_push_back(llvm_basicblock, Fn->BasicBlocks, FalseBlock);
+
+ /* One branch of the cond can be void, if it never returns. For
+ example A ? throw : E */
+ if (TREE_TYPE(TREE_OPERAND(exp, 2)) != void_type_node) {
+ unsigned BStart = 0, BSize = 0;
+ llvm_value *Val = llvm_expand_lvalue_expr(Fn, TREE_OPERAND(exp, 2),
+ &BStart, &BSize);
+ assert(BStart == 0 && BSize == 0 &&
+ "Cannot handle lvalue bitfields in condexpr yet!");
+ append_inst(Fn, create_store_inst(Val, ResultLoc, 0));
+ } else {
+ llvm_expand_expr(Fn, TREE_OPERAND (exp, 2), 0);
+ }
+
+ /* Add the branch and continue block */
+ llvm_emit_label(Fn, ContinueBlock);
+
+ /* Load the result out of the temporary */
+ Result = append_inst(Fn, create_load_inst("tmp", ResultLoc, 0));
+ break;
+ }
}
return cast_if_type_not_equal(Fn, Result, Ty);
-Chris
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
More information about the llvm-bugs
mailing list