[Bug c/57813] New: Change of global variable ignored

2013-07-03 Thread daniel.oertwig at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813

Bug ID: 57813
   Summary: Change of global variable ignored
   Product: gcc
   Version: 4.8.0
Status: UNCONFIRMED
  Severity: major
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: daniel.oertwig at gmail dot com
Target: avr51

Created attachment 30450
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30450action=edit
Source code relating to the problem

Hi, I assume this to be a bug in how the compiler optimizes its code.
Unfortunately, I don't know enough about how the gcc works to narrow down the
source of the problem.

If it's me (or my code), please tell me what I am doing wrong.

Basically I have a function operating on a global variable. This function calls
another function which changes this global variable. But the changed value is
not used by the calling function afterwards.


Task * Task_getNextReady()
{
uint8_t priority;
if (taskInfo.ready[0]) priority = 0;
else if (taskInfo.ready[1]) priority = 1;
else if (taskInfo.ready[2]) priority = 2;
else if (taskInfo.ready[3]) priority = 3;
else if (taskInfo.ready[4]) priority = 4;
else if (taskInfo.ready[5]) priority = 5;
else if (taskInfo.ready[6]) priority = 6;
else priority = 7;
// Before call to function: taskInfo.ready[priority] == task6
// After call to function: taskInfo.ready[priority] == task7
// Return value = 10
taskInfo.ready[priority]-wakeTime = Task_enforceTimeslice(priority);
// Changed task6-wakeTime = 10
// Unchanged task7-wakeTime
// Return value is task7, which is correct.
return taskInfo.ready[priority];
}

I guess i could solve this by making the variable volatile, but I don't think
that this would be correct.


[Bug c/57813] Change of global variable ignored

2013-07-03 Thread daniel.oertwig at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813

--- Comment #1 from Daniel Oertwig daniel.oertwig at gmail dot com ---
Created attachment 30451
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30451action=edit
Disassembly of the relating parts (from *.elf file, i.e. after linking)


[Bug c/57813] Change of global variable ignored

2013-07-03 Thread daniel.oertwig at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813

--- Comment #2 from Daniel Oertwig daniel.oertwig at gmail dot com ---
Oh, I am compiling with:

CFLAGS := 
CFLAGS += -Os
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -ffreestanding
CFLAGS += -Wall -Wextra
CFLAGS += -Wstrict-prototypes
CFLAGS += -Wundef
CFLAGS += -Wsign-compare
CFLAGS += -std=gnu99 #-std=c99
CFLAGS += -g3 -gdwarf-2 -pg
CFLAGS += -fstack-usage


LDFLAGS :=
LDFLAGS += -Wl,--relax

using avr-gcc. There are no warnings.


[Bug c/57813] Change of global variable ignored

2013-07-03 Thread daniel.oertwig at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813

Daniel Oertwig daniel.oertwig at gmail dot com changed:

   What|Removed |Added

 Status|RESOLVED|UNCONFIRMED
 Resolution|INVALID |---

--- Comment #4 from Daniel Oertwig daniel.oertwig at gmail dot com ---

Task * Task_getNextReady()
{
uint8_t priority;
if (taskInfo.ready[0]) priority = 0;
else if (taskInfo.ready[1]) priority = 1;
else if (taskInfo.ready[2]) priority = 2;
else if (taskInfo.ready[3]) priority = 3;
else if (taskInfo.ready[4]) priority = 4;
else if (taskInfo.ready[5]) priority = 5;
else if (taskInfo.ready[6]) priority = 6;
else priority = 7;
time_t delay = Task_enforceTimeslice(priority);
Task * next = taskInfo.ready[priority];
next-wakeTime = delay;
return next;
}

This code solves the issue, using the correct value of the global variable.
Please tell me if I am wrong, but I think this code should be equivalent to the
original code.

(Task_enforceTimeslice is not declared as pure, I checked just to be sure)


[Bug c/57813] Change of global variable ignored

2013-07-03 Thread daniel.oertwig at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813

--- Comment #5 from Daniel Oertwig daniel.oertwig at gmail dot com ---
(In reply to Andrew Pinski from comment #3)
   taskInfo.ready[priority]-wakeTime = Task_enforceTimeslice(priority);
 
 This is the same as:
   (*taskInfo.ready[priority]).wakeTime = Task_enforceTimeslice(priority);
 
 Which means either the compiler can read the value of
 taskInfo.ready[priority] before or after the function call to
 Task_enforceTimeslice because there is no sequence point between them.

Shouldn't the compiler recognize that enforceTimeslice is altering the global
variable?

[Bug c/57813] Change of global variable ignored

2013-07-03 Thread daniel.oertwig at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813

--- Comment #8 from Daniel Oertwig daniel.oertwig at gmail dot com ---
Ok, so: Is this behaviour part of the language or a bug in gcc?
I could not find any documentation specifying that a sequence point should be
inbetween the (side-effect) evaluation of the function call and the (value)
evaluation of the assignment.