[PATCH][Win] Fix assertion failure when passing 'nul' in input to cc1.
Andrea Di Biagio
andrea.dibiagio at gmail.com
Tue Apr 29 04:21:19 PDT 2014
Hi all,
On Windows, a device is a file of type 'FILE_TYPE_CHAR'.
In the case of 'nul', function 'getStatus' in Path.inc returns an
instance of 'file_status' with fields 'nFileSizeHigh' and
'nFileSizeLow' left uninitialized.
Later on, this might cause the triggering of an assertion failure in
MemoryBuffer.cpp:
Assertion Failed: NextLocalOffset + FileSize + 1 > NextLocalOffset &&
NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset && "Ran out of
source locations!"
I spotted this problem when running the following command from the command line:
`clang -cc1 -x c nul -dM -E`
This patch fixes the problem modifying the constructor of
'file_status' in llvm/Support/FileSystem.h.
I have split the patch in two parts:
* An LLVM patch fixes the problem setting by default to zero all the
fields of file_status (excluding Type and Perms) in the constructor of
file_size in FileSystem.h.
* A Clang patch that adds a test to verify that the assertion no longer happens.
The test requires to be run on windows. To make that test work fine, I
modified clang/test/lit.py to add feature `system-windows' if
platform.system() is 'Windows'.
Please let me know if ok to submit.
Thanks,
Andrea Di Biagio
SN Systems - Sony Computer Entertainment Group.
-------------- next part --------------
Index: test/Frontend/windows-nul.c
===================================================================
--- test/Frontend/windows-nul.c (revision 0)
+++ test/Frontend/windows-nul.c (working copy)
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -dM -E nul -o /dev/null
+
+// REQUIRES: system-windows
+
+// Verify that cc1 doesn't crash with an assertion failure
+// in MemoryBuffer.cpp due to an invalid file size reported
+// when the Windows 'nul' device is passed in input.
+
Index: test/lit.cfg
===================================================================
--- test/lit.cfg (revision 207520)
+++ test/lit.cfg (working copy)
@@ -344,6 +344,9 @@
# This is used by debuginfo-tests/*block*.m and debuginfo-tests/foreach.m.
if platform.system() in ['Darwin']:
config.available_features.add('system-darwin')
+elif platform.system() in ['Windows']:
+ # For tests that require Windows to run.
+ config.available_features.add('system-windows')
# ANSI escape sequences in non-dumb terminal
if platform.system() not in ['Windows']:
-------------- next part --------------
Index: include/llvm/Support/FileSystem.h
===================================================================
--- include/llvm/Support/FileSystem.h (revision 207520)
+++ include/llvm/Support/FileSystem.h (working copy)
@@ -166,14 +166,22 @@
perms Perms;
public:
file_status() : Type(file_type::status_error) {}
- file_status(file_type Type) : Type(Type) {}
#if defined(LLVM_ON_UNIX)
+ file_status(file_type Type) : fs_st_dev(0), fs_st_ino(0), fs_st_mtime(0),
+ fs_st_uid(0), fs_st_gid(0), fs_st_size(0), Type(Type),
+ Perms(perms_not_known) {}
+
file_status(file_type Type, perms Perms, dev_t Dev, ino_t Ino, time_t MTime,
uid_t UID, gid_t GID, off_t Size)
: fs_st_dev(Dev), fs_st_ino(Ino), fs_st_mtime(MTime), fs_st_uid(UID),
fs_st_gid(GID), fs_st_size(Size), Type(Type), Perms(Perms) {}
#elif defined(LLVM_ON_WIN32)
+ file_status(file_type Type) : LastWriteTimeHigh(0), LastWriteTimeLow(0),
+ VolumeSerialNumber(0), FileSizeHigh(0), FileSizeLow(0),
+ FileIndexHigh(0), FileIndexLow(0), Type(Type),
+ Perms(perms_not_known) {}
+
file_status(file_type Type, uint32_t LastWriteTimeHigh,
uint32_t LastWriteTimeLow, uint32_t VolumeSerialNumber,
uint32_t FileSizeHigh, uint32_t FileSizeLow,
@@ -183,6 +191,8 @@
VolumeSerialNumber(VolumeSerialNumber), FileSizeHigh(FileSizeHigh),
FileSizeLow(FileSizeLow), FileIndexHigh(FileIndexHigh),
FileIndexLow(FileIndexLow), Type(Type), Perms(perms_not_known) {}
+ #else
+ file_status(file_type Type) : Type(Type) {}
#endif
// getters
More information about the cfe-commits
mailing list