* [PATCH 1/2] kernel.h: Add BUILD_BUG_ON_USED() macro.
2011-11-22 1:31 [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used David Daney
@ 2011-11-22 1:31 ` David Daney
2011-11-22 4:35 ` Linus Torvalds
2011-11-22 1:31 ` [PATCH 2/2] hugetlb: Replace BUG() with BUILD_BUG_ON_USED() for dummy definitions David Daney
2011-11-22 8:42 ` [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used DM
2 siblings, 1 reply; 6+ messages in thread
From: David Daney @ 2011-11-22 1:31 UTC (permalink / raw)
To: ralf, Linus Torvalds, Andrew Morton, David Rientjes
Cc: linux-kernel, linux-arch, David Daney
From: David Daney <david.daney@cavium.com>
We can place this in definitions that we expect the compiler to remove
by dead code elimination. If this assertion fails, we get a nice
error message at build time.
The GCC function attribute error("message") was added in version 4.3,
so we define a new macro __linktime_error(message) to expand to this
for GCC-4.3 and later. This will give us an error diagnostic from the
compiler on the line that fails. For other compilers
__linktime_error(message) expands to nothing, and we have to be
content with a link time error, but at least we will still get a build
error.
BUILD_BUG_ON_USED() expands to the undefined function
__build_bug_on_used_failed() and will fail at link time if the
compiler ever emits code for it. On GCC-4.3 and later,
attribute((error())) is used so that the failure will be noted at compile
time instead.
Signed-off-by: David Daney <david.daney@cavium.com>
---
include/linux/compiler-gcc4.h | 1 +
include/linux/compiler.h | 4 +++-
include/linux/kernel.h | 16 ++++++++++++++++
3 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index dfadc96..2f40791 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -29,6 +29,7 @@
the kernel context */
#define __cold __attribute__((__cold__))
+#define __linktime_error(message) __attribute__((__error__(message)))
#if __GNUC_MINOR__ >= 5
/*
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 320d6c9..4a24354 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -293,7 +293,9 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
#ifndef __compiletime_error
# define __compiletime_error(message)
#endif
-
+#ifndef __linktime_error
+# define __linktime_error(message)
+#endif
/*
* Prevent the compiler from merging or refetching accesses. The compiler
* is also forbidden from reordering successive instances of ACCESS_ONCE(),
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index b93c66e..ebe54515 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -666,6 +666,7 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
#define BUILD_BUG_ON_ZERO(e) (0)
#define BUILD_BUG_ON_NULL(e) ((void*)0)
#define BUILD_BUG_ON(condition)
+#define BUILD_BUG_ON_USED() (0)
#else /* __CHECKER__ */
/* Force a compilation error if a constant expression is not a power of 2 */
@@ -704,6 +705,21 @@ extern int __build_bug_on_failed;
if (condition) __build_bug_on_failed = 1; \
} while(0)
#endif
+
+/**
+ * BUILD_BUG_ON_USED - break compile if used.
+ *
+ * If you have some code that you expect the compiler to eliminate at
+ * build time, you should use BUILD_BUG_ON_USED to detect if it is
+ * unexpectedly used.
+ */
+#define BUILD_BUG_ON_USED() \
+ do { \
+ extern void __build_bug_on_used_failed(void) \
+ __linktime_error("BUILD_BUG_ON_USED failed"); \
+ __build_bug_on_used_failed(); \
+ } while (0)
+
#endif /* __CHECKER__ */
/* Trap pasters of __FUNCTION__ at compile-time */
--
1.7.2.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/2] hugetlb: Replace BUG() with BUILD_BUG_ON_USED() for dummy definitions.
2011-11-22 1:31 [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used David Daney
2011-11-22 1:31 ` [PATCH 1/2] kernel.h: Add BUILD_BUG_ON_USED() macro David Daney
@ 2011-11-22 1:31 ` David Daney
2011-11-22 8:42 ` [PATCH 0/2] Stop some of the abuse of BUG() where compile time checks should be used DM
2 siblings, 0 replies; 6+ messages in thread
From: David Daney @ 2011-11-22 1:31 UTC (permalink / raw)
To: ralf, Linus Torvalds, Andrew Morton, David Rientjes
Cc: linux-kernel, linux-arch, David Daney
From: David Daney <david.daney@cavium.com>
The file linux/hugetlb.h has many places where dummy symbols were
defined so that the main source code would contain fewer:
#ifdef CONFIG_HUGETLBFS
If there were any misuse of these symbols, the only symptom would be
an OOPS at runtime. Change the BUG() to BUILD_BUG_ON_USED() to catch
any such abuse at compile time instead.
Signed-off-by: David Daney <david.daney@cavium.com>
---
include/linux/hugetlb.h | 15 ++++++++-------
1 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index d9d6c86..0067191 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -85,11 +85,11 @@ static inline unsigned long hugetlb_total_pages(void)
return 0;
}
-#define follow_hugetlb_page(m,v,p,vs,a,b,i,w) ({ BUG(); 0; })
+#define follow_hugetlb_page(m,v,p,vs,a,b,i,w) ({ BUILD_BUG_ON_USED(); 0; })
#define follow_huge_addr(mm, addr, write) ERR_PTR(-EINVAL)
-#define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; })
-#define hugetlb_prefault(mapping, vma) ({ BUG(); 0; })
-#define unmap_hugepage_range(vma, start, end, page) BUG()
+#define copy_hugetlb_page_range(src, dst, vma) ({ BUILD_BUG_ON_USED(); 0; })
+#define hugetlb_prefault(mapping, vma) ({ BUILD_BUG_ON_USED(); 0; })
+#define unmap_hugepage_range(vma, start, end, page) BUILD_BUG_ON_USED()
static inline void hugetlb_report_meminfo(struct seq_file *m)
{
}
@@ -100,8 +100,9 @@ static inline void hugetlb_report_meminfo(struct seq_file *m)
#define pmd_huge(x) 0
#define pud_huge(x) 0
#define is_hugepage_only_range(mm, addr, len) 0
-#define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) ({BUG(); 0; })
-#define hugetlb_fault(mm, vma, addr, flags) ({ BUG(); 0; })
+#define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) \
+ ({BUILD_BUG_ON_USED(); 0; })
+#define hugetlb_fault(mm, vma, addr, flags) ({ BUILD_BUG_ON_USED(); 0; })
#define huge_pte_offset(mm, address) 0
#define dequeue_hwpoisoned_huge_page(page) 0
static inline void copy_huge_page(struct page *dst, struct page *src)
@@ -186,7 +187,7 @@ static inline void set_file_hugepages(struct file *file)
#else /* !CONFIG_HUGETLBFS */
#define is_file_hugepages(file) 0
-#define set_file_hugepages(file) BUG()
+#define set_file_hugepages(file) BUILD_BUG_ON_USED()
static inline struct file *hugetlb_file_setup(const char *name, size_t size,
vm_flags_t acctflag, struct user_struct **user, int creat_flags)
{
--
1.7.2.3
^ permalink raw reply related [flat|nested] 6+ messages in thread