First Last Prev Next    No search results available
Details
: [llvm-gcc] ?: operator as lvalue not implemented
Bug#: 131
: tools
: llvm-gcc
Status: RESOLVED
Resolution: FIXED
: All
: All
: 1.0
: P2
: normal
: 1.1

:
: compile-fail
:
:
  Show dependency tree - Show dependency graph
People
Reporter: Misha Brukman <brukman+bugs@uiuc.edu>
Assigned To: Chris Lattner <clattner@apple.com>

Attachments


Note

You need to log in before you can comment on or make changes to this bug.

Related actions


Description:   Opened: 2003-11-18 16:14
Reduced from linux-2.4.22/arch/x86/kernel/pageattr.c

% cat pageattr.i
typedef struct { unsigned long pgprot; } pgprot_t;

void split_large_page(unsigned long addr, pgprot_t prot)
{
  (addr ? prot : ((pgprot_t) { 0x001 } )).pgprot;
}
% llvm-gcc pageattr.i
ERROR: In function c_llvm_expand_lvalue_expr:5607, tree not handled by LLVM yet!
 <cond_expr 0x40019840
    type <record_type 0x40277e00 pgprot_t type_0 SI
        size <integer_cst 0x4001b7d0 constant 32>
        unit size <integer_cst 0x4001b7f8 constant 4>
        align 32 symtab 0 alias set -1
        fields <field_decl 0x40277c40 pgprot type <integer_type 0x4001d540 long
unsigned int>
            unsigned SI file pageattr.i line 429
            size <integer_cst 0x4001b208 constant 32>
            unit size <integer_cst 0x4001b294 constant 4>
            align 32 offset_align 32
            offset <integer_cst 0x4001b884 constant 0>
            bit offset <integer_cst 0x4001b924 constant 0> context <record_type
0x40277cb0> arguments <integer_cst 0x4001b884 0>> context <translation_unit_decl
0x4001d070>>
    side-effects
    arg 0 <eq_expr 0x4026a570
        type <integer_type 0x4001d3f0 int SI size <integer_cst 0x4001b208 32>
unit size <integer_cst 0x4001b294 4>
            align 32 symtab 0 alias set -1 precision 32 min <integer_cst
0x4001b26c -2147483648> max <integer_cst 0x4001b280 2147483647>
            pointer_to_this <pointer_type 0x4022abd0>>
       
        arg 0 <parm_decl 0x40277e70 addr type <integer_type 0x4001d540 long
unsigned int>
            unsigned used SI file pageattr.i line 431 size <integer_cst
0x4001b208 32> unit size <integer_cst 0x4001b294 4>
            align 32 context <function_decl 0x40279000 split_large_page> result
<integer_type 0x4001d540 long unsigned int> initial <integer_type 0x4001d540
long unsigned int> arg-type <integer_type 0x4001d540 long unsigned int>
arg-type-as-written <integer_type 0x4001d540 long unsigned int> chain <parm_decl
0x40277ee0 prot>>
        arg 1 <integer_cst 0x40278c1c constant 0>>
    arg 1 <compound_literal_expr 0x40278ce4 type <record_type 0x40277e00 pgprot_t>
        side-effects
        arg 0 <decl_stmt 0x40278cd0 arg 0 <var_decl 0x40279150>>>
    arg 2 <parm_decl 0x40277ee0 prot type <record_type 0x40277e00 pgprot_t>
        used SI file pageattr.i line 431 size <integer_cst 0x4001b7d0 32> unit
size <integer_cst 0x4001b7f8 4>
        align 32 context <function_decl 0x40279000 split_large_page> result
<record_type 0x40277e00 pgprot_t> initial <record_type 0x40277e00 pgprot_t>
arg-type <record_type 0x40277e00 pgprot_t> arg-type-as-written <record_type
0x40277e00 pgprot_t>>>
pageattr.i: In function `split_large_page':

pageattr.i:433: internal compiler error: in c_llvm_expand_lvalue_expr, at
llvm-expand.c:5607
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://llvm.cs.uiuc.edu> for instructions.
------- Comment #1 From Chris Lattner 2003-11-18 17:47:45 -------
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

First Last Prev Next    No search results available