LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 9984 - -fms-compatibility: Clang should form a wide string literal from L#macro_arg in a function-like macro
Summary: -fms-compatibility: Clang should form a wide string literal from L#macro_arg ...
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: C++ (show other bugs)
Version: trunk
Hardware: PC All
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks: 13707
  Show dependency tree
 
Reported: 2011-05-22 05:25 PDT by Jason Filsinger
Modified: 2014-12-14 22:19 PST (History)
8 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jason Filsinger 2011-05-22 05:25:00 PDT
the following code produces an error:


#define TESTL(x) L#x
const wchar_t* a = L"Hello World";
const wchar_t* b = TESTL(Hello World);


The preprocessor appears to ignore the L inside the define as the literal declaring the string as a wide string.   The code not using the macro passes without error.

Here is the analyzer output:

"Use of undeclared identifier 'L'"

This fails on both using the analyzer that ships with XCode 4.0.1 as well as svn trunk (test at revision 131851).
Comment 1 Douglas Gregor 2011-05-22 10:27:42 PDT
Clang is behaving correctly here (as does GCC). You can't both stringize a token and concatenate in one step. Instead, use:

  #define TESTL2(x) L##x 
  #define TESTL(x) TESTL2(#x)
  const wchar_t* a = L"Hello World";
  const wchar_t* b = TESTL(Hello World);
Comment 2 Jason Filsinger 2011-05-22 15:53:59 PDT
(In reply to comment #1)
> Clang is behaving correctly here (as does GCC). You can't both stringize a
> token and concatenate in one step. Instead, use:
> 
>   #define TESTL2(x) L##x 
>   #define TESTL(x) TESTL2(#x)
>   const wchar_t* a = L"Hello World";
>   const wchar_t* b = TESTL(Hello World);

It also works with:

#define TESTL(x) L###x
const wchar_t* a = L"Hello World";
const wchar_t* b = TESTL(Hello World);

I wasn't sure of the desired behaviour of "L#x" in clang (or that GCC doesn't allow for it either),  I ran into it while trying to analyze some Microsoft example code while working on a Visual Studio plugin for the clang analyzer.   Is this something that should be added to the clang Microsoft extensions?
Comment 3 Reid Kleckner 2014-06-17 10:54:31 PDT
IMO we should consider lexing this as a single wide string literal in -fms-compatibility mode.  There appear to be lots of Windows applications using this idiom to form wide string literals from macro arguments.
Comment 4 Alexey Bataev 2014-12-14 22:19:23 PST
Fixed in revision 224228