This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C2000: pointer passed to assembler function gets dereferenced

Other Parts Discussed in Thread: CONTROLSUITE

Hi,

I encountered this multiple times now and think it's time to ask. I use C2000 compiler v6.2.6.

I have assembler functions called by C. The assembler functions are declared in a C header, an example is:

    void foo(void *dest, const void *src, unsigned len);

Now under certain unknown circumstances it seems the compiler messes up the function call. As per the calling convention, dest is passed in XAR4, src in XAR5 and len in AL. What happens from time to time is that src is passed in XAR5, but not the address (i. e. the pointer) as expected, but the value pointed to by src: XAR5 is dereferenced and written back to itself before the assembler function is executed...

It happens for example when an array (char[]) is passed as src, but not when a string literal (const char *) is passed.

Am I doing something wrong?

Upgrading to and trying out a latest compiler version would be an option of course, but I would like to know before if this bug is already known and/or fixed from v6.2.6.

Thanks
Felix

  • Felix Deichmann said:
    What happens from time to time is that src is passed in XAR5, but not the address (i. e. the pointer) as expected, but the value pointed to by src: XAR5 is dereferenced and written back to itself before the assembler function is executed

    I am unable to reproduce this behavior.  Please submit a test case.  You will probably need to preprocess the source file which exhibits the unexpected behavior.  Also show all the compiler command line options.

    Thanks and regards,

    -George

  • I think I can finally reproduce it.

    Now for my above example of function declaration, when you call asm_fun(dest, str, 1) with str being declared like:

        extern char *str;

    and defined as:

        char str[] = "0";

    then it triggers the bogus case that XAR5, starting with the assembler function, will contain the first char of str, i. e. 0x30!

    If you instead declared:

        extern char str[];

    it works well and XAR5 will contain the "address of the first char of str".

    Compiler is called with:

    -v28 -ml -mt --cla_support=cla0 --float_support=fpu32 --vcu_support=vcu0 -O3 --opt_for_speed=5 [many --include_path ... follow] --gcc [many --define ... follow] --diag_warning=225 --display_error_number --diag_wrap=off -k

    Does this already help you? Else I will have to find time to work out a reproducible test case, as I cannot provide our production code.

    Felix

  • That is a bug in your code.

    With the mismatched types, your observations can easily be explained. At the linking stage, str will denote the location of a character array (char arr[]), while the declaration said that it will denote the location of a pointer. C's implicit "array to pointer" conversion cannot and will not be applied here, because the code that uses arr thinks it's a pointer. In fact, you invoked undefined behavior: "All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined."

  • Markus Moll said:

    With the mismatched types, your observations can easily be explained. At the linking stage, str will denote the location of a character array (char arr[]), while the declaration said that it will denote the location of a pointer. C's implicit "array to pointer" conversion cannot and will not be applied here, because the code that uses arr thinks it's a pointer. In fact, you invoked undefined behavior: "All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined."

    I see, got tricked by external linkage... :) Thanks! I guess this is also one of the rarer cases where no compiler warning is possible at all (?).

  • There is some link-time type checking done at -O4, but I'm not sure it would catch this case
  • Archaeologist said:
    There is some link-time type checking done at -O4, but I'm not sure it would catch this case

    Now getting a bit off-topic, but I have never been able to use -O4 (at least not with v6.2.6) and check that, as it always complained about "redeclared symbols with incompatible type", although (a) these symbols are not redeclared at all, and it works with -O3, and/or (b) the redeclaration is exactly the same like:

    error: symbol "AdcResult" redeclared with incompatible type:
       "volatile struct ADC_RESULT_REGS"
       in "C:\xxxyyy\Firmware\drivers\F2806x\F2806x_Adc.h" at
       line 367 and:
       "volatile struct ADC_RESULT_REGS"
       in "../Firmware/drivers/F2806x/F2806x_GlobalVariableDefs.c" at line 31)

    [...]

    fatal error #10192: Failed linktime optimization

    We are quite happy with -O3 and I didn't find the time to search for the cause of this (and maybe it is already solved in recent compiler versions).

  • We've seen this error message a lot. There have been some bugs in the type checking, but all known bugs are fixed in 6.2.6. Usually the error is caused by a subtle difference in the declaration, such as using a typedef in one case but not the other. I note that the error message says the second declaration comes from the C file and not the header file. If you could, remove the declaration in the C file and include the header file instead to see if it resolves the problem. It may be that the C declaration contains a member that is an incomplete type which is confusing the type checking code. The fastest way to get to the bottom of it would be to post a test case demonstrating the error.
  • Archaeologist said:
    If you could, remove the declaration in the C file and include the header file instead to see if it resolves the problem. It may be that the C declaration contains a member that is an incomplete type which is confusing the type checking code. The fastest way to get to the bottom of it would be to post a test case demonstrating the error.

    As you can probably imagine from looking at the file names, these are C files and headers from controlSUITE for the 2806x line (device support, v1.3.6)... So it would be good if someone from TI could have a look, as test cases are all over the place. :)