[cfe-dev] Assignment expression in C++ returns its right operand (A possible bug)

Xiaolong Tang xiaolong.snake at gmail.com
Thu Feb 16 14:37:34 PST 2012


Hi everyone, 

I found a surprise in the llvm code generated by clang. (I am using
clang version 3.0. And the revision is git-svn-id:
https://llvm.org/svn/llvm-project/cfe/trunk@137823). Though my
original example is the swap function for STL string, I created one
simple example as below to show the problem I found. 

class A {
public:
  int *foo(int *s) {
    return x = s;
  }
private:
  int *x;
};

int main() {
  A a;
  int x;
  int *px = &x;
  a.foo(px);
  return 0;
}

In the above example, foo supposes to return x. However, its
corresponding llvm bitcode (by clang) seems to return s. The llvm
bitcode is as below:

define linkonce_odr i32* @_ZN1A3fooEPi(%class.A* %this, i32* %s) nounwind uwtable ssp align 2 {
entry:
  %this.addr = alloca %class.A*, align 8, !tbaa !10, !clang.vardecl.type !10
  %s.addr = alloca i32*, align 8, !tbaa !5, !clang.vardecl.type !5
  store %class.A* %this, %class.A** %this.addr, align 8, !tbaa !10
  store i32* %s, i32** %s.addr, align 8, !tbaa !5
  %this1 = load %class.A** %this.addr, !tbaa !10
  %tmp = load i32** %s.addr, align 8, !tbaa !5
  %x = getelementptr inbounds %class.A* %this1, i32 0, i32 0
  store i32* %tmp, i32** %x, align 8, !tbaa !5
  ret i32* %tmp
}

Note that the register value denoted by %tmp is returned, but %tmp is
the value of the second parameter. (This does not agree with the c++
semantics.) 

Again I am using clang version 3.0. And the revision is git-svn-id:
https://llvm.org/svn/llvm-project/cfe/trunk@137823

If I am correct and the above problem has been fixed, can someone
point to me the commit where the problem is fixed? If I am somehow
wrong, can someone give me any explanation? 

Thanks!

Xiaolong

 



More information about the cfe-dev mailing list