Bug 39133

Summary: wrong optimization produces output of false warning (conditional PHIs)
Product: gcc Reporter: Corin <corinl>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: av1474, corinl, edwin+gccbugs, fnf, gcc-bugs, manu
Priority: P3    
Version: unknown   
Target Milestone: 4.4.0   
Host: x86_64 Target: x86_64
Build: 4.2.3-2ubuntu7 Known to work:
Known to fail: Last reconfirmed:
Bug Depends on:    
Bug Blocks: 24639    

Description Corin 2009-02-08 22:04:24 UTC
piece of code inside contained in class methode (starting line 263):
---
char *buf;
if (!strncmp(in->loc.path,"/translators/",strlen("/translators/")))
{
	translator_c *xl = translator_from_path(in->loc.path);
	if (xl)
	{
		char *loc = in->loc.path+strlen("/translators/")+strlen(xl->name);
		LOG_DEBUG(log, "control_get_data, xl '%s', loc '%s'", xl->name, loc);
		buf = xl->control_get_data(loc);
	}
}
else
{
	char *loc = in->loc.path;
	LOG_DEBUG(log, "control_get_data, internal, loc '%s'", loc);
	buf = control_get_data(loc);
}

if (buf)
{
	MEM_NEW(persistent, persistent_c());
	persistent->read_mode = true;
	persistent->data = buf;
	persistent->data_len = strlen(persistent->data);

	out->ref = (xl_ref_t) persistent;
	out->op_errno = 0;
}
else
{
	out->op_errno = ENOENT;
}
---


compiling with the following options works fine (no warnings, no errors):
---
CFLAGS=-Wall -Werror -fPIC -pthread -I../common -I../../common -I../../../common -I../shared -I../../shared -I../../../shared -O0 -g
---


compiling with the following options produces a warning (=error);
---
CFLAGS=-Wall -Werror -fPIC -pthread -I../common -I../../common -I../../../common -I../shared -I../../shared -I../../../shared -O3 -ffast-math
---
cc1plus: warnings being treated as errors
main.cpp: In member function »virtual void main_c::fop_open(stack_frame_t*)«:
main.cpp:263: Warnung: »buf« könnte in dieser Funktion uninitialisiert verwendet werden
make: *** [main.o] Fehler 1
---
Fehler = Error
»buf« könnte in dieser Funktion uninitialisiert verwendet werden = "buf could be used uninitialized in this function"
---

as you can clearly see, buf could never be used uninitialized so this must be a compiler/optimizer bug.
Comment 1 Corin 2009-02-08 22:07:25 UTC
Oh sorry, I just see that "buf" could be used uninitialized for sure (if xl==NULL). but well, shouldn't this warning then be issued all the times? so the bug is now reversed -> "missing warning" instead of "false warning" ;)
Comment 2 Richard Biener 2009-02-08 22:18:43 UTC
The warning should be there at -O0 starting with G++ 4.4.
Comment 3 Corin 2009-02-12 07:26:00 UTC
Thanks for the info. Unluckily I just found the bug reported first now for sure:

Code:

// setuid/setgid only affect the current thread
#define FS_PERMS_SET(_uid, _gid) \
	bool check_permissions_local = check_permissions; \
	uid_t fs_perms_uid_orig; \
	gid_t fs_perms_gid_orig; \
	if (check_permissions_local) \
	{ \
		fs_perms_uid_orig = setfsuid(_uid); \
		fs_perms_gid_orig = setfsgid(_gid); \
	}

// setuid/setgid only affect the current thread
#define FS_PERMS_RESTORE() \
	if (check_permissions_local) \
	{ \
		setfsuid(fs_perms_uid_orig); \
		setfsgid(fs_perms_gid_orig); \
	}

#define FOP_ERRNO(R) out->op_errno=((R==0)?0:errno)

...
line 934:
	FS_PERMS_SET(in->uid, in->gid);

	FOP_ERRNO(statvfs(path, &out->stbuf));

	FS_PERMS_RESTORE();
...

Error report:

main.cpp:934: Warnung: »fs_perms_gid_orig« könnte in dieser Funktion uninitialisiert verwendet werden
main.cpp:934: Warnung: »fs_perms_uid_orig« könnte in dieser Funktion uninitialisiert verwendet werden

This is not true, as at this point the variables are only written to. They are only ever read (and even later) if they have first been written to.
Comment 4 Corin 2009-02-12 07:37:57 UTC
here's the copy from the precompiled header file (.ii), may be it helps:
(check_permissions_local removed, it was just for test..same error as before)

 uid_t fs_perms_uid_orig; gid_t fs_perms_gid_orig; if (check_permissions) { fs_perms_uid_orig = setfsuid(in->uid); fs_perms_gid_orig = setfsgid(in->gid); };

 out->op_errno=((statvfs(path, &out->stbuf)==0)?0:(*__errno_location ()));

 if (check_permissions) { setfsuid(fs_perms_uid_orig); setfsgid(fs_perms_gid_orig); };
Comment 5 Manuel López-Ibáñez 2009-02-12 11:22:38 UTC
At the moment of warning, the compiler does not know that the uninitialized variables are only used if they have been set before. Hence, the warning.

This will require conditional PHIs (or some other way to detect that some PHI operands are never reached).

*** This bug has been marked as a duplicate of 36550 ***