Bug 59895 - Updates to global variables not consistent across translation units when FLTO is enabled
Summary: Updates to global variables not consistent across translation units when FLTO...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-01-21 01:05 UTC by Aleksandr Dobkin
Modified: 2014-01-21 05:08 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
PoC code (22.57 KB, application/x-gzip)
2014-01-21 01:05 UTC, Aleksandr Dobkin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Aleksandr Dobkin 2014-01-21 01:05:48 UTC
Created attachment 31902 [details]
PoC code

Modifications of global variables are sometimes not carried out properly when FLTO is enabled. Short PoC follows.

// FILE bug-flto.cpp //
#include <vector>
#include <stdio.h>

#include "shared.h"

std::vector<int> globalvec;

S1::S1() {
    printf("S1() called\n");
    globalvec.push_back(42);
    printf("S1() globalvec.size() = %d\n", (int) globalvec.size());
}

int main() {
    printf("main globalvec.size() = %d\n", (int) globalvec.size());
    return 0;
}

// FILE tu2.cpp
#include "shared.h"

S1 s1;

// FILE shared.h
#pragma once

struct S1 {
    S1();
};

// FILE Makefile
run: bug-flto
	./bug-flto

bug-flto: bug-flto.o tu2.o
	g++-4.8 -O -flto -obug-flto bug-flto.o tu2.o

bug-flto.o: bug-flto.cpp
	g++-4.8 -O -flto -obug-flto.o -c bug-flto.cpp
	
tu2.o: tu2.cpp
	g++-4.8 -O -flto -otu2.o -c tu2.cpp
	
clean:
	rm *.o
	rm
Comment 1 Aleksandr Dobkin 2014-01-21 01:07:48 UTC
Output I get is:

S1() called
S1() globalvec.size() = 1
main globalvec.size() = 0

tested with g++-4.8 (Ubuntu 4.8.1-2ubuntu1~12.04) 4.8.1
Comment 2 Andrew Pinski 2014-01-21 01:39:50 UTC
The order of initializing s1 and globalvec is undefined in C++ and that is the effect you are seeing.  If s1 and globalvec are declared in the same TU, the order is defined by the order in the source itself.
Comment 3 Andrew Pinski 2014-01-21 01:46:34 UTC
So in this case here, s1 is being initialized first and then globalvec gets initialized which changes the size back to 0.
Comment 4 Aleksandr Dobkin 2014-01-21 05:08:50 UTC
(In reply to Andrew Pinski from comment #3)
> So in this case here, s1 is being initialized first and then globalvec gets
> initialized which changes the size back to 0.

Thanks for the explanation. I've verified this does appear to be the case.