@@ -1862,3 +1862,62 @@ impl EarlyLintPass for IncompleteFeatures {
18621862 } ) ;
18631863 }
18641864}
1865+
1866+ declare_lint ! {
1867+ pub INVALID_VALUE ,
1868+ Warn ,
1869+ "an invalid value is being created (such as a NULL reference)"
1870+ }
1871+
1872+ declare_lint_pass ! ( InvalidValue => [ INVALID_VALUE ] ) ;
1873+
1874+ impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for InvalidValue {
1875+ fn check_expr ( & mut self , cx : & LateContext < ' a , ' tcx > , expr : & hir:: Expr ) {
1876+
1877+ const ZEROED_PATH : & [ Symbol ] = & [ sym:: core, sym:: mem, sym:: zeroed] ;
1878+ const UININIT_PATH : & [ Symbol ] = & [ sym:: core, sym:: mem, sym:: uninitialized] ;
1879+
1880+ /// Return `false` only if we are sure this type does *not*
1881+ /// allow zero initialization.
1882+ fn ty_maybe_allows_zero_init ( ty : Ty < ' _ > ) -> bool {
1883+ use rustc:: ty:: TyKind :: * ;
1884+ match ty. sty {
1885+ // Primitive types that don't like 0 as a value.
1886+ Ref ( ..) | FnPtr ( ..) | Never => false ,
1887+ // Conservative fallback.
1888+ _ => true ,
1889+ }
1890+ }
1891+
1892+ if let hir:: ExprKind :: Call ( ref path_expr, ref _args) = expr. node {
1893+ if let hir:: ExprKind :: Path ( ref qpath) = path_expr. node {
1894+ if let Some ( def_id) = cx. tables . qpath_res ( qpath, path_expr. hir_id ) . opt_def_id ( ) {
1895+ if cx. match_def_path ( def_id, & ZEROED_PATH ) ||
1896+ cx. match_def_path ( def_id, & UININIT_PATH )
1897+ {
1898+ // This conjures an instance of a type out of nothing,
1899+ // using zeroed or uninitialized memory.
1900+ // We are extremely conservative with what we warn about.
1901+ let conjured_ty = cx. tables . expr_ty ( expr) ;
1902+
1903+ if !ty_maybe_allows_zero_init ( conjured_ty) {
1904+ cx. span_lint (
1905+ INVALID_VALUE ,
1906+ expr. span ,
1907+ & format ! (
1908+ "the type `{}` does not permit {}" ,
1909+ conjured_ty,
1910+ if cx. match_def_path( def_id, & ZEROED_PATH ) {
1911+ "zero-initialization"
1912+ } else {
1913+ "being left uninitialized"
1914+ }
1915+ ) ,
1916+ ) ;
1917+ }
1918+ }
1919+ }
1920+ }
1921+ }
1922+ }
1923+ }
0 commit comments