summaryrefslogtreecommitdiff
path: root/support/regression/tests/bug1839277.c
blob: 68c81b7d124f569700c4c9b50ce87bdd46909da1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
    bug 1839277 & 1839299
*/

#include <testfwk.h>

const __code struct Value {
  const __code char* Name[2];
} Values[2]= {{{"abc", "def"}}, {{"ghi", "jkl"}}};

char i = 1;

void
testBug1839277 (void)
{
  const char __code* const * volatile p;
  unsigned long v = 0;
//first subexpression 'Values[0].Name' is evaluated as follows:
//mov     r2,#_Values
//mov     r3,#(_Values >> 8)
//mov     r4,#(_Values >> 16) ;this is wrong - should be 'mov r4,#128' shouldn't it?
//second subexpression 'Values[1].Name' is evaluated as follows:
//mov     a,#0x04
//add     a,#_Values
//mov     r2,a
//clr     a
//addc    a,#(_Values >> 8)
//mov     r3,a
//mov     r4,#128 ;this is all right
  p = i ? Values[0].Name : Values[1].Name;
#if defined(SDCC_mcs51)
  v = (unsigned long)p;
  ASSERT ((unsigned char)(v >> 16) == 0x80);
#endif

//everything is all right with explicit typecast - but why do I need it?
  p = i ? (const char __code* const *)Values[0].Name : (const char __code* const *)Values[1].Name;
#if defined(SDCC_mcs51)
  v = (unsigned long)p;
  ASSERT ((unsigned char)(v >> 16) == 0x80);
#endif

//this is the best/optimal version - again with explicit typecast
//Question: Why is it necessary to have explicit typecast to make things right?
  p = i ? (const char __code* const __code*)Values[0].Name : (const char __code* const __code*)Values[1].Name;
#if defined(SDCC_mcs51)
  v = (unsigned long)p;
  ASSERT ((unsigned char)(v >> 16) == 0x80);
#endif
}

void
testBug1839299 (void)
{
  const char __code* const * volatile p;
  unsigned long v = 0;
//'Values[0].Name' subexpression is evaluated as follows first:
//mov     r2,#_Values
//mov     r3,#(_Values >> 8)
//mov     r4,#(_Values >> 16) ;this is wrong - see bug 1839277
  p = i ? Values[0].Name : Values[1].Name;
//this assignment has some sideeffect on the following one
//in fact it is the evaluation of 'Values[0].Name' itself has the effect, not the assignment
  p = Values[0].Name;
//'Values[0].Name' subexpression is evaluated as follows second:
//mov     r2,#_Values
//mov     r3,#(_Values >> 8)
//mov     r4,#0x00 ;this is different from first occurrence but also wrong
  p = i ? Values[0].Name : Values[1].Name;
#if defined(SDCC_mcs51)
  v = (unsigned long)p;
  ASSERT ((unsigned char)(v >> 16) == 0x80);
#endif
}