LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 12226 - 'expected relocatable expression' with unsigned char array initialized from string literal
Summary: 'expected relocatable expression' with unsigned char array initialized from s...
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: C++ (show other bugs)
Version: trunk
Hardware: PC Linux
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-10 08:22 PST by Luboš Luňák
Modified: 2012-04-14 21:52 PDT (History)
4 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Luboš Luňák 2012-03-10 08:22:26 PST
Steps to reproduce:

$ echo 'static const unsigned char array[] = { "a" };' >a.cpp
$ clang++ -std=c++11 a.cpp
fatal error: error in backend: expected relocatable expression

$ clang++ --version
SUSE Linux clang version 3.1 (trunk 152441) (based on LLVM 3.1svn)
Target: x86_64-unknown-linux-gnu
Thread model: posix

The problem goes away if not compiling in C+11 mode or if the array is of plain char type instead of unsigned char.

Even if the code is actually invalid (I can't tell), at least a proper error message should be given.
Comment 1 Nico Weber 2012-04-14 18:06:47 PDT
Stack: 

tests-MacBook-Pro-2:src test$ gdb --args  ~/src/llvm-rw/Debug+Asserts/bin/clang  -cc1 -std=c++11  a.cpp -emit-obj
GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Mon Aug  8 20:32:45 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries ... done

(gdb) break cc1_main.cpp:42
Breakpoint 1 at 0x10000176e: file /Users/test/src/llvm-rw/tools/clang/tools/driver/cc1_main.cpp, line 42.
(gdb) run
Starting program: /Users/test/src/llvm-rw/Debug+Asserts/bin/clang -cc1 -std=c++11 a.cpp -emit-obj
Reading symbols for shared libraries ++......................... done

Breakpoint 1, LLVMErrorHandler (UserData=0x106701500, Message=@0x7fff5fbfcb30) at /Users/test/src/llvm-rw/tools/clang/tools/driver/cc1_main.cpp:42
42	  DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData);
(gdb) bt
#0  LLVMErrorHandler (UserData=0x106701500, Message=@0x7fff5fbfcb30) at /Users/test/src/llvm-rw/tools/clang/tools/driver/cc1_main.cpp:42
#1  0x0000000102202207 in llvm::report_fatal_error (Reason=@0x7fff5fbfcc80) at /Users/test/src/llvm-rw/lib/Support/ErrorHandling.cpp:66
#2  0x0000000102018525 in llvm::MCContext::FatalError (this=0x106876220, Loc=@0x7fff5fbfcc98, Msg=@0x7fff5fbfcc80) at /Users/test/src/llvm-rw/lib/MC/MCContext.cpp:332
#3  0x000000010200e139 in llvm::MCAssembler::evaluateFixup (this=0x10671c8a0, Layout=@0x7fff5fbfcef0, Fixup=@0x10671ce10, DF=0x10671e140, Target=@0x7fff5fbfcd38, Value=@0x7fff5fbfcd30) at /Users/test/src/llvm-rw/lib/MC/MCAssembler.cpp:246
#4  0x000000010200f40a in llvm::MCAssembler::handleFixup (this=0x10671c8a0, Layout=@0x7fff5fbfcef0, F=@0x10671e140, Fixup=@0x10671ce10) at /Users/test/src/llvm-rw/lib/MC/MCAssembler.cpp:546
#5  0x000000010200f97c in llvm::MCAssembler::Finish (this=0x10671c8a0) at /Users/test/src/llvm-rw/lib/MC/MCAssembler.cpp:615
#6  0x00000001020399ee in llvm::MCObjectStreamer::FinishImpl (this=0x10671c7c0) at /Users/test/src/llvm-rw/lib/MC/MCObjectStreamer.cpp:277
#7  0x0000000102032e62 in (anonymous namespace)::MCMachOStreamer::FinishImpl (this=0x10671c7c0) at /Users/test/src/llvm-rw/lib/MC/MCMachOStreamer.cpp:407
#8  0x000000010203f629 in llvm::MCStreamer::Finish (this=0x10671c7c0) at /Users/test/src/llvm-rw/lib/MC/MCStreamer.cpp:683
#9  0x00000001019cef47 in llvm::AsmPrinter::doFinalization (this=0x10671ceb0, M=@0x106709710) at /Users/test/src/llvm-rw/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:948
#10 0x000000010218d856 in llvm::FPPassManager::doFinalization (this=0x106714e60, M=@0x106709710) at /Users/test/src/llvm-rw/lib/VMCore/PassManager.cpp:1517
#11 0x000000010218dfa9 in llvm::FPPassManager::runOnModule (this=0x106714e60, M=@0x106709710) at /Users/test/src/llvm-rw/lib/VMCore/PassManager.cpp:1501
#12 0x000000010218e1bd in llvm::MPPassManager::runOnModule (this=0x1067110f0, M=@0x106709710) at /Users/test/src/llvm-rw/lib/VMCore/PassManager.cpp:1553
#13 0x000000010218e897 in llvm::PassManagerImpl::run (this=0x106710db0, M=@0x106709710) at /Users/test/src/llvm-rw/lib/VMCore/PassManager.cpp:1636
#14 0x000000010218eac1 in llvm::PassManager::run (this=0x1067105f0, M=@0x106709710) at /Users/test/src/llvm-rw/lib/VMCore/PassManager.cpp:1665
#15 0x0000000100207e9b in (anonymous namespace)::EmitAssemblyHelper::EmitAssembly (this=0x7fff5fbfd800, Action=clang::Backend_EmitObj, OS=0x106709340) at /Users/test/src/llvm-rw/tools/clang/lib/CodeGen/BackendUtil.cpp:447
#16 0x0000000100207a91 in clang::EmitBackendOutput (Diags=@0x106701500, CGOpts=@0x106804068, TOpts=@0x106804408, LOpts=@0x106700fa0, M=0x106709710, Action=clang::Backend_EmitObj, OS=0x106709340) at /Users/test/src/llvm-rw/tools/clang/lib/CodeGen/BackendUtil.cpp:459
#17 0x000000010034d3e1 in clang::BackendConsumer::HandleTranslationUnit (this=0x106709380, C=@0x106828400) at /Users/test/src/llvm-rw/tools/clang/lib/CodeGen/CodeGenAction.cpp:160
#18 0x00000001003b4022 in clang::ParseAST (S=@0x106840200, PrintStats=false, SkipFunctionBodies=false) at /Users/test/src/llvm-rw/tools/clang/lib/Parse/ParseAST.cpp:108
#19 0x0000000100079888 in clang::ASTFrontendAction::ExecuteAction (this=0x1067011a0) at /Users/test/src/llvm-rw/tools/clang/lib/Frontend/FrontendAction.cpp:416
#20 0x000000010034c222 in clang::CodeGenAction::ExecuteAction (this=0x1067011a0) at /Users/test/src/llvm-rw/tools/clang/lib/CodeGen/CodeGenAction.cpp:421
#21 0x00000001000794a7 in clang::FrontendAction::Execute (this=0x1067011a0) at /Users/test/src/llvm-rw/tools/clang/lib/Frontend/FrontendAction.cpp:335
#22 0x00000001000441a5 in clang::CompilerInstance::ExecuteAction (this=0x106700f00, Act=@0x1067011a0) at /Users/test/src/llvm-rw/tools/clang/lib/Frontend/CompilerInstance.cpp:672
#23 0x0000000100017671 in clang::ExecuteCompilerInvocation (Clang=0x106700f00) at /Users/test/src/llvm-rw/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:183
#24 0x0000000100001129 in cc1_main (ArgBegin=0x7fff5fbff270, ArgEnd=0x7fff5fbff288, Argv0=0x106700d58 "/Users/test/src/llvm-rw/Debug+Asserts/bin/clang", MainAddr=0x100011270) at /Users/test/src/llvm-rw/tools/clang/tools/driver/cc1_main.cpp:166
#25 0x00000001000114b9 in main (argc_=5, argv_=0x7fff5fbffae8) at /Users/test/src/llvm-rw/tools/clang/tools/driver/driver.cpp:357
Comment 2 Nico Weber 2012-04-14 18:18:21 PDT
Difference between c++11 and old c++:


tests-MacBook-Pro-2:src test$   ~/src/llvm-rw/Debug+Asserts/bin/clang  -cc1 a.cpp -emit-llvm  -o -
; ModuleID = 'a.cpp'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-darwin11.3.0"

@_ZL5array = internal constant <{ [2 x i8], i8 }> <{ [2 x i8] c"a\00", i8 0 }>, align 1



tests-MacBook-Pro-2:src test$   ~/src/llvm-rw/Debug+Asserts/bin/clang  -cc1 a.cpp -emit-llvm -std=c++11 -o -
; ModuleID = 'a.cpp'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-darwin11.3.0"

@.str = private unnamed_addr constant [2 x i8] c"a\00", align 1
Comment 3 Nico Weber 2012-04-14 18:32:06 PDT
Bisecting over the prebuilt binaries at http://is.gd/chromeclang suggests this broke between 148039 and 148911 (late january 2012)
Comment 4 Nico Weber 2012-04-14 19:44:34 PDT
This was introduced in r148178 ( http://llvm.org/viewvc/llvm-project?view=rev&revision=148178 )
Comment 5 Nico Weber 2012-04-14 20:24:11 PDT
Err, cut off the c++11 llvm output above. In full:

tests-MacBook-Pro-2:src test$ third_party/llvm-build/Release+Asserts/bin/clang -cc1 a.cpp -std=c++11 -emit-llvm -o -
; ModuleID = 'a.cpp'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-darwin11.3.0"

@.str = private unnamed_addr constant [2 x i8] c"a\00", align 1
@_ZL5array = internal constant [2 x i8] [i8 ptrtoint ([2 x i8]* @.str to i8), i8 0], align 1
Comment 6 Richard Smith 2012-04-14 21:02:17 PDT
Interesting. The relevant check (ExprConstant.cpp, in ArrayExprEvaluator::VisitInitListExpr) was inspired by matching code in CGExprAgg.cpp's AggExprEmitter::VisitInitListExpr, which has the same bug (although the bug appears to be benign in that case). In C++98 mode, we compile this:

void f() { unsigned char c[] = { "foobar" }; }

... into this:

@_ZZ1fvE1c = private unnamed_addr constant <{ [7 x i8], i8, i8, i8, i8, i8, i8 }> <{ [7 x i8] c"foobar\00", i8 0, i8 0, i8 0, i8 0, i8 0, i8 0 }>, align 1

define void @_Z1fv() nounwind uwtable {
  ; ...
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* getelementptr inbounds (<{ [7 x i8], i8, i8, i8, i8, i8, i8 }>* @_ZZ1fvE1c, i32 0, i32 0, i32 0), i64 7, i32 1, i1 false)

In both cases, we accidentally initialize the first element of an array of N chars with an array built out of the string literal.
Comment 7 Richard Smith 2012-04-14 21:52:48 PDT
We had this same bug in three different places! Fixed in r154756.